Search Unity

NavMeshAgent acts weird after responding to Physics

Discussion in 'Scripting' started by BobbyDoogle, Jan 20, 2014.

  1. BobbyDoogle

    BobbyDoogle

    Joined:
    Dec 3, 2013
    Posts:
    15
    I have a simple NavMesh enemy with an attached rigidbody that is on a simple ground object. I have a playerRef game object that is my player, and the enemy simply finds a path to that transform.position of this playerRef, the path is current calculated each frame. Everything works fine until the enemy is hit, which causes a physics reaction (the enemy getting hit by a projectile or melee attack). The physics work fine, but then the path finding gets weird. The enemy seems to still path find, but to some odd location, or it shudders and moves sporadically. If I make the enemy Kinematic it doesn't have this issue, but of course, cannot be effected by physics, which is my goal.

    void Update () {
    playerLoc = playerRef.transform.position;
    GetComponent<NavMeshAgent>().destination = playerLoc;
    }

    What can I do to allow this object to react to physics and if still on the NavMesh, find a new path properly. Also what is the recommended way to check if the object is off navmesh (if the physics knocks it off)?
     
  2. BobbyDoogle

    BobbyDoogle

    Joined:
    Dec 3, 2013
    Posts:
    15
    I solved this issue and wanted to report it for future viewers. The key is to deactivate the NavMeshAgent completely then reactivate after the physics action is complete. I used this code when the enemy is hit:

    in Declaration: private NavMeshAgent navAgent;

    in Start: navAgent = GetComponent<NavMeshAgent> ();

    When the enemy is hit:
    navAgent.enabled=false;
    rigidbody.isKinematic = false;
    rigidbody.useGravity = true;
    Invoke ("EnableNavMesh",1F);

    Then the EnableNavMesh method simply reverses these actions:
    rigidbody.isKinematic = true;
    rigidbody.useGravity = false;
    navAgent.enabled=true;

    Oh, and one more critical item, in the Update add a condition that requires the NavMeshAgent to be active to compute path:
    if (navAgent.enabled==true)
    {
    GetComponent<NavMeshAgent>().destination = playerLoc;
    }