How to stop NavMeshAgent immediately?

So I have a situation where I need the Agent to stop at the exact spot that he is in the moment I ask him to do so.

I’m current using the NavMeshAgent.Stop() but he still slides about 0.1cm before actually stopping.

I noticed the old documentation had a NavMeshAgent.Stop(true):

But that is now deprecated. I also tried to set his velocity = Vector3.zero before stopping him but still the agent slides.

Here are my NavMeshAgent settings in case it helps:
79668-agentsettings.jpg

Any help very appreciated!

I know this is old, but since all the current answers are downvoted and I don’t see the correct solution here, I’ll post it. To stop:

gameObject.GetComponent<NavMeshAgent>().isStopped = true;

And to start it again:

gameObject.GetComponent<NavMeshAgent>().isStopped = false;

As there’s not a single clear answer, but only options here and there without explaining what each option actually does, I’ll give a clear and full answer that can be done with the latest non-beta version of the AI Navigation package (1.1.4 at the moment).

As shown in the answers given over the course of the years, there are multiple ways of handling the NavMeshAgent to make it stop, but the results from one method to another may be completely different depending on your setup and the kind of NavMesh Data that is being used by the NavMeshAgent.

The first thing to ask yourself is if you want the NavMeshAgent to fully stop, but keep track of its destination or if you want it to fully stop and forget everything it has to do.

  1. If you want it to forget everything, then you can just call NavMeshAgent.ResetPath(); and this will clear any navigation data held by the NavMeshAgent. While this option is clear on its goal, you got to remember that clearing the navigation data from a NavMeshAgent will purge the NavMeshAgent’s cache to the Garbage Collector (GC). So, if you constantly adding new destinations to a large amount of NavMeshAgent in a scene (let’s say, a strategy game like Warcraft or Starcraft) and want to micro-manage the AI on their path via code, you might not want to use ResetPath() (especially on mobile or WebGL builds) because you’ll be giving a lot of redundant tasks to the GC and, yes, this can results in some temporary memory allocation issues if done on a large scale.

If you want the Agent to stop, but keep track of its destination until a new one is given and avoid relocating memory, there are a few ways and some includes some additional features.

  1. The simplest method is to use SetDestination(); to the NavMeshAgent’s position itself.
    Note that while this is simple, it’s also the most risked/unstable method because even if you set a destination to itself, if the Agent may not actually consider itself as “at destination” immediately. This can result in the Agent rotating to some seemingly random direction (it’s not random, but might appears as such) or even having the Agent turn around and move a strange small loop. If you got such results, that’s due to the nature of the destination being a Vector3 value and the NavMesh Data which might includes some complication. You may have float precision issues where the value of Vector3 given is slightly different from the Agent’s own Vector3 by a fraction or it could be that the calculation from the NavMesh Data results in a different position than its own current (this is due to the fact that when you set a new destination, the actual resulting position is a conversion of that destination.)
    Also, this method can result in some strange unpredictable behaviors if you attempt to force/rotate the Agent toward a direction afterward such as having the Agent reposition itself because of some internal AI conflicts.

  2. Another option is to set the NavMeshAgent speed to 0.
    This is, in my opinion, the best option if you plan on stopping, but not resetting the NavMeshAgent because you can control the speed gradually (avoid an immediate unrealistic stop) and you don’t have to worry about unseen/unplanned behavior in the AI.
    With that said it also comes with a feature that can be both a PRO and a CON depending on what you’re going for and how you manage the destination which is that while its speed is 0, the Agent will continue to “look” toward its next path’s point toward its target. If you plan on not updating the destination, but want to be able to turn the Agent around while it’s immobile, then this won’t work. With that said, if you plan on rotating the agent to follow a target while its speed is a 0, you can simply cache its “old” destination and, while its speed is at 0, update it current destination to the target’s position and, if needed, resume its previous movement by setting the destination as its old one (the one cached previously) once you raise its speed value back to normal.
    So, yes, while this option is simple to use, it does requires a bit of preparation, codes-wise, to apprehend what’s happening to the Agent.

  3. Using NavMeshAgent.isStopped = true;:
    This is basically a “pause” method for the NavMeshAgent. This can be a good solution if you want the Agent to resume on the exact same path later. Unlike setting the speed to 0, this method will allow you full control on the Agent’s game object, but any changes applied will force the agent to recalculate its path once you set isStopped as false later on. This can results in some performances impact on the device’s CPU if you’re using this on multiple object and, while they are stopped, if their position is changed drastically.
    For example, if you plan on having some kind of ragdoll effect where a character is pushed by some forces, then raise back up, you should NOT use this method if there are any risks that the character ends up outside of the NavMesh Data range (outside of the “blue zone floor” zone) or even on a different NavMeshSurface (such as if you have multiple NavMeshSurfaces in your scene). If you plan on using this method in a scene that has complex NavMeshSurface transitions, you got to plan some ways of handling the situation so that the NavMeshAgent knows when it has to keep updating its path or when it just have to forget everything and restart anew.

As a side note, here’s a few thing you should NEVER do:

• Never disable a NavMeshAgent component to just stop it.
When you disable a component, you basically crap any cached data held by the component to the GC. If you enable the component back on, Unity is then forced to cache back a new registry of the whole component into action. Since the AI Navigation changed from a scene-based cached system to an object/instance-based cached system, there are fewer problem with disabling a NavMeshAgent, but the stress it may generate on the CPU and CG as well as the effect on Memory is real. This doesn’t mean that you should never disable a NavMeshAgent at all, but you should do it for something semi-persistant and not just temporary or frequent.

For example, if a player or NPC dies, you could disable the NavMeshAgent until it’s resurrected.
This is especially useful if you also have a rigidbody on the object. Just don’t forget that disabling the NavMeshAgent will resume any physics/forces (such as gravity) that might have been “handled” by it and if there’s a visible difference between the NavMesh data and the actual visual floor, enabling the NavMeshAgent back on might result in the object instantly teleporting back onto the NavMeshData “grid”. (It will look like it’s “popping” back onto the blue zone in the editor.)

• Never add or use any Rigidbody to take control over a NavMeshAgent
The relation between a Rigidbody and a NavMeshAgent, in Unity, is a strange thing that required a lot of under-the-hood work to make it happening. Long story short, if you got a Rigidbody and a NavMeshAgent on a game object, the NavMeshAgent “communicate” with the Rigidbody whatever instruction it requires to follow its path. It’s a per-frame process, meaning that it will have some performance impact. If you either change the rigidbody’s velocity to 0 or freeze its position, it will not stop the NavMeshAgent to constantly nags the physics’ engine (via a rigidbody) with its calculations on how to proceed so that the object can move toward its destination even if it doesn’t move in results.

Note that you can add some forces or velocity to a rigidbody while it has a NavMeshAgent.
For instance, if you want to pushes the Agent with some strong wind or, as previously mentioned, want to have a ragdoll effect where a character is launched, you can do it even if the object has a NavMeshAgent, but you got to understand that whenever you do it, it’s a relatively expensive per-frame process on the CPU via Unity physics’ engine.

1 Like

Just had this issue and solved it by setting the NavMeshAgent’s destination to the object’s current position. Basically:

GetComponent<NavMeshAgent>().SetDestination( transform.position );

I use

GetComponent<NavMeshAgent>().velocity = Vector3.zero;

I agree with Antonio. I just .enable = false the navmesh. Make sure autobraking is on , that stops the agent faster ( than NOT on) but disabling the navmesh is how I do it

GetComponent<NavMeshAgent>().enabled = false;

Set the velocity to zero and then set isStopped to true. Will stop the agent immediately. Another hack you can try is that SetDestination to self ie SetDestination(transform.position). In the second hack the script should be on the agent to be stopped as transform.position has been used.

Not sure if this is new, but what about ResetPath

Update: In practice, I have been using: navMeshAgent.speed = 0 to reliably stop my character.

This is quite old but now there is a more clean solution:

GetComponent<NavMeshAgent>().ResetPath();

Simply turn off Auto-Braking and set Acceleration sky high (like 20000). Pretty straight-forward, but I can’t promise if that suit your game.