1
\$\begingroup\$

Somebody told me that don't use the physical collision detection(don't use Collider,Rigidbody,Raycasting) because performance loss.instead of it use the mathematical way for collision detection.

Physical collision detection:

enter image description here

Raycasting is a very useful and powerful tool available on the physics engine. It allows us to fire a ray on a certain direction with a certain length and it will let us know if it hit something. This however, is an expensive operation; its performance is highly influenced by the ray’s length and type of colliders on the scene.

in this game enemies randomly create in some points.is it that better instead of checking by Raycasting call the fire(); method(foreach plant in them row) when created zombies?

enter image description here

mathematical collision detection:

enter image description here

Vector3.Distance(a,b) is the same as (a-b).magnitude.

float dist = Vector3.Distance(other.position, transform.position);

is better checking distance than using mentioned components(Collider,Rigidbody). he believes using Colliders and Rigidbody component produce lag in game.

\$\endgroup\$
4
\$\begingroup\$

First of all, "performance loss" is only an argument in situations where performance actually matters. When your framerate is good enough and your code is easier to read and maintain with colliders and raycasting, then by all means, stop fixing what isn't broken.

But in the case of a lane defense game like plants vs. zombies, you have very simplified game physics where the Unity collision detection engine indeed seems overkill.

  1. Objects can only collide with objects in the same lane
  2. When two objects are in the same lane, all that matters is the x-coordinate and the width of the objects involved.
  3. All objects only move in one direction and only collide head-on. So you only need to check for collisions in one direction.

First you need to know which lane each object is in. There are several ways you could do that.

  • You could make each lane an own object in your scene hierarchy and all objects on that lane child-objects.
  • You could have a public int lane variable on each object which says which lane it is on.
  • You could have a List<GameObject> for each lane somewhere.

Each of these approaches has advantages and disadvantages. Pick the one which seems to fit best into your overall architecture.

If you want to check collisions of an object obj with other objects, get all objects in the same lane. Then if you want to check for a collision to the right, do if (other.x - obj.x) < (obj.width + other.width) / 2 for each eligible object in that lane. To check for a collision to the left, do if (obj.x - other.x) < (obj.width + other.width) / 2.


A side-note about the Rigidbody component: You only need rigidbodies when you want to have kinetic physics (gravity, mass, friction, objects bouncing off each other, etc.). When your game isn't supposed to have anything like that, you shouldn't put a rigidbody on anything. I am not saying that adding realistic physics couldn't be an interesting spin on the overused tower defense formula, but when you want to create an authentic Plants vs. Zombies clone, you likely don't want that. When all you want is collision detection, then all you need is a Collider.

\$\endgroup\$
  • \$\begingroup\$ I was going to say the same so +1. Unless you are having performance problems, and this is a significant part of the work done, optimizing this isn't going to really get you anything. Good enough is good enough, by definition! \$\endgroup\$ – Alan Wolfe Dec 5 '16 at 16:13
  • \$\begingroup\$ Re: the side-note, I know in earlier versions of Unity moving a collider without a rigidbody was very slow. I understand they've made this much much faster in recent versions than it used to be, but I haven't verified whether it's faster or slower than moving a kinematic rigidbody. This sounds like it could be a case worth profiling each way to see if it makes a difference.(If you're using the physics system at all, that is) \$\endgroup\$ – DMGregory Dec 5 '16 at 23:47
1
\$\begingroup\$

It all depends on your game. Typically you would use distance methods combined with other methods like GJK and SAT to calculate the collision detection mathematically. Using raycasting (in combination with the methods above) is good for things that move very fast. If you have two objects moving towards each other at a high enough speed such that they pass each other during the one frame, then you would need to raycast to make sure that you dont travel through the object.

e.g.:

frame 1   |   frame 2  
[A]><[B]  |  <[B]  [A]> 

(because you are just adding velocities to their positions, you are not moving them one pixel/unit at a time)

However, if you are making a game like Plants V Zombies as you pictured, you could get away with far less.
You know that objects are only on one axis and things fit into cells. You can simply check whether or not x values overlap/pass each other.
Or, more simply, check what cell an object is in and see if something else was there already

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.