- Home /
NavMeshAgent & Collisions / Physics
Hi,
I have a enemy unit with a NvaMeshAgent & RigidBody attached. I have disabled Kinematic disabled so I they can collide. When I run in to the enemy units or apply physics to them the NavMeshAgent gets screwed up.
Is there a way to fix this?
Do I have to enable Kinematic and handle the collisions myself?
Thanks in advance.
Think I am having the same issue, any chance you found a fix?
Answer by FenixShadow · Feb 17, 2018 at 03:51 PM
First of all, check out this section in the manual about mixing a NavMesh Agent with other components, including a Rigidbody. It provides some good information, including that if you have a NavMesh Agent and non-kinematic Rigidbody on the same game object there will be a race condition and unexpected behavior will result. https://docs.unity3d.com/Manual/nav-MixingComponents.html
One option to still allow for physical forces on the game object with the NavMesh Agent component is to put some script on that object that temporarily disables the NavMesh Agent and sets the Rigidbody to non-kinematic. For example:
void OnCollisionEnter(Collision collision)
{
GetComponent<NavMeshAgent>().enabled = false;
GetComponent<Rigidbody>().isKinematic = false;
}
That will temporarily prevent the NavMesh Agent from trying to move the object while it's being moved by physics forces. However, if you do this, you have to have some way in which to reenable the NavMesh Agent and set the Rigidbody back to kinematic when you are ready for the NavMesh Agent to take control again. I've used a simple timer to give the collision force some time to resolve before giving control back to the NavMesh Agent. This works better with predictable collisions in which you know for about how long the physical forces should have control.
bool isPhysical;
float knockbackTime = 1;
float knockbackCooldown;
void Update()
{
if (isPhysical)
{
// Add the time since the last Update
knockbackCooldown += Time.deltaTime;
if (knockbackCooldown > knockbackTime)
{
GetComponent<NavMeshAgent>().enabled = true;
GetComponent<Rigidbody>().isKinematic = true;
isPhysical = false;
knockbackCooldown = 0;
}
}
}
Another method that @ChazBass suggested on Reddit is creating the force manually at the time of the collision and then lerping it down to zero before restoring control to the NavMesh Agent. A similar approach, but one which gives you a little more control over the force applied to the object and the point at which you restore control to the NavMesh Agent.