[SOLVED]How can I stop Navmesh agent sliding in Unity5?

Hi, Im trying to make Pause function on my enemies (without changing timescale).

Those characters are attached NavMeshAgent component, and using SetDestination() to following player.

When the game is paused, I called function “NavMeshAgent.Stop(true)” in Unity 4.3 .

The (true) option named “stopUpdates” means stop immediately NavMeshAgent without sliding.
http://docs.unity3d.com/412/Documentation/ScriptReference/NavMeshAgent.Stop.html

But this option is deleted later than Unity 5, I guess.

Somebody said change setting acceleration value to higher, but it’s dosen’t work.

And I tried using “NavMeshAgent.updatePosition = false”.
Then enemy character stopped, but the NavMeshAgent component was keeping moving separate from parent Object(enemy character model).

So when I set “NavMeshAgent.updatePosition = true”, the enemy character warp to unintentional position.

Please tell me how to solve this issue.
SFMPE.

3 Likes

Through many trial and error, I found solution finally.

Set velocity Vector3.zero before call Stop();.

navMeshAgent.velocity = Vector3.zero;
navMeshAgent.Stop();

http://docs.unity3d.com/ScriptReference/NavMeshAgent-velocity.html

If it will be used as reference for someone.

18 Likes

Thanks !!!

YOU MY FRIEND, ARE THE REAL MVP
need hours to find this.

1 Like

Thank you - I also searched for that like half a day :slight_smile:

Thank you very much

Thank You so much!!!

Thank you! I’ve been searching for this solution for ages! One minor addition, NavMeshAgent.Stop() is now deprecated, and NavMeshAgent.isStopped = true should be used instead (the naming is horrible, it should only be a getter).

Additionally, if you want to restore the movement of the agent after pausing, store the velocity in a variable before setting it to Vector3.zero, and check for agent.isStopped == true before restoring it.

Example:

    IEnumerator MovementCoroutine() {
        agent.isStopped = false;
        Vector3 unpausedSpeed = Vector3.zero;
        while (!WithinRange(target, Range)) {
            if (GameTime.Paused)
            {
                // emulate effect of Time.timeScale = 0
                agent.velocity = Vector3.zero;
                agent.isStopped = true;
            }
            else
            {
                // restore velocity from before pause
                if (agent.isStopped)
                {
                    agent.isStopped = false;
                    agent.velocity = unpausedSpeed;
                }
                agent.SetDestination(target.position);
                agent.speed = originalSpeed / GetNavMeshCost();
                unpausedSpeed = agent.velocity;
            }
            yield return null;
        }

        agent.isStopped = true;
        movementCoroutine = null;
    }

I found a better solution, just do
Agent.velocity = Agent.desiredVelocity;
in the update method. This will ignore aceleration and make the agent go to the target with no sliding or overshooting the target

2 Likes

Thank you, I solved it simply by doing this.