0
\$\begingroup\$

I would like to know more about how collision detection works in Unity especially when character controllers and NavmeshAgents get involved.

For example, how can I detect collision between NavmeshAgent and a CharacterController? I have added a sphere collider to my NavmeshAgent, but it doesn't seem to detect a collision unless I set it to "IsTrigger". I have tried OnCollisionEnter(), OnControllerColliderHit() and OnTriggerEnter(). OnTriggerEnter() seems to be the only one that works and only when I enable "IsTrigger".

How come the other two don't work? Shouldn't they? What if I didn't want to make the collider a trigger?

\$\endgroup\$
  • \$\begingroup\$ Presumably you started by reviewing the documentation on this matter (in particular, the Collision Action Matrix at the bottom)? \$\endgroup\$ – DMGregory Jun 10 at 18:30
  • \$\begingroup\$ @DMGregory Yes I came across that, but it doesn't explain how things work when navmeshagents or character controllers get involved. \$\endgroup\$ – xcrypt Jun 10 at 18:31
  • \$\begingroup\$ If you want collision with a NavMeshAgent, it needs a kinematic Rigidbody, as explained in the docs. The CharacterController's OnControllerColliderHit is also documented. \$\endgroup\$ – DMGregory Jun 10 at 18:39
  • \$\begingroup\$ @DMGregory I have read those couple times, but do I always need to use OnControllerColliderHit when working with character controller? And why can I not detect a collision between a non-trigger kinematic rigidbody collider (in the NavMeshAgent's case) and a Character controller? This doesn't seem so transparent in the documentation \$\endgroup\$ – xcrypt Jun 10 at 18:50
  • \$\begingroup\$ This is explained in an existing answer here - OnCollisionEnter is part of the physics collision response. Kinematic bodies and CharacterControllers don't experience a physics collision response - they don't bounce off an obstacle unless your code tells them to. So the OnCollisionEnter method is not called unless at least one of the participants has a dynamic rigidbody (as shown in the matrix), because that's the only case that experiences a physics collision response. \$\endgroup\$ – DMGregory Jun 10 at 18:55
0
\$\begingroup\$

So, after some research, debate and thinking, I came to the following conclusions: basically all collisions that aren't charactercontrollers are explained in the documentation.

When a Character Controller gets involved, you can still use the other methods aswell (OnCollisionEnter() and OnTriggerEnter()), provided the other collider suits the conditions (non-kinematic attached rigidbody or an IsTrigger Collider, respectively)

To detect collision between two charactercontrollers, or between a charactercontroller and a rigidbody, you can also use OnControllerColliderHit(), on condition that you are using the intrinsic Move() method.

To detect collisions between two kinematic rigidbodies, you need to enable "IsTrigger" on one of the colliders. If in this case you still want the kinematic rigidbody to push around other objects, you need to add a second collider with "IsTrigger" set to false. This is also how you should detect collision with navmeshagents, since they don't function with non-kinematic rigidbodies.

| improve this answer | |
\$\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.