Moving Agents on NavMesh with Unity 2021
In this article, we’ll use NavMesh and NavMeshAgent to move our AI game object along a path of waypoints denoted by the blue game objects.
Let’s add an AI character represented by a simple sphere game object to our scene.
Go ahead and create a material and give it some color to differentiate it from the rest of the scene.
To make our AI game object a NavMesh Agent, we simply need to add the “Nav Mesh Agent” component.
Now, my waypoints have been solid objects and I want to make it clear in my scene that they are not.
By modifying the Alpha level of my Base Map color of my Point_mat material and setting Surface Type to “Transparent”, I’ve given them a ghost-like appearance.
If we run our project right now, nothing will happen.
Scripting the AI Agent to Move Across the NavMesh
Let’s create an AI script and assign it to the AI game object.
Telling a NavMeshAgent to Move to a Destination
You can tell an agent to start calculating a path simply by setting the The fundamental object in Unity scenes, which…
Unity has a handy how-to guide on telling a NavMeshAgent to move to a destination.
We can see from the Unity provided code example above, we really just need an agent and a destination.
For our demonstration, we’ll make our AI game object / NavMeshAgent choose a random waypoint and move to it.
In our script, we’ll need to add a using statement for UnityEngine.AI.
I’ve also declared some class variables to hold the destination, the NavMeshAgent, and waypoint related data.
In our script, we can see the two key components underlined, the NavMeshAgent and the destination assignment to it.
After assigning the NavMeshAgent component from the attached game object, we get our Waypoints by searching for their parent game object.
We then add those waypoint game objects to an array.
A simple method, GetRandomWaypoint, uses Random.Range to grab one of those waypoint game objects from the array.
And finally, we tell the navMeshAgent the desired destination.
Note that we start at an index of 1 for stored waypoints array.
This is because the array stores the parent game object’s transform as well.
If we hit play, we can see that the code works as intended.
Utilizing the Waypoints to Create a Path of Movement
Above we can see the desired movement behavior we will be implementing.
A > B > C > D > E > F
I’ve updated the AI script with some new variables to accomplish our task.
We’ll need to know when we’ve reached the current waypoint, the last waypoint, what the current waypoint position we are moving to is, and the index identifiers for current and last waypoints.
I’ve essentially moved the random waypoint logic to its own method, MoveAIRandomly() and disabled it.
All I need to add to the Start() method for our new path system is an initial value for _currentWP;
Now, initially I set this to 1, but as you’ll see in the Update() method, the first loop through Update() will add 1 to this variable before setting and moving to the first waypoint.
As such, _currentWP will = 1 when our AI game object is first told to move towards a waypoint.
Our Update() method runs every frame, so we want to do as little work in here as possible so as not to kill our framerate.
Thus, if our NavMeshAgent’s remaining distance to the current waypoint is indicating that it has not arrived, I simply want to break out of the Update() method and not run any of the remaining code within it.
Otherwise, we have reached the current waypoint and I want to set the new waypoint and get our NavMeshAgent moving towards it.
Using bool flags, we can accurately track when to update our current waypoint and when not to.
This method does exactly what you think it does.
This method fires once the NavMeshAgent reaches the current waypoint and needs to update the current waypoint variables to the next waypoint in the path.
The method first checks to make sure that the current waypoint is not the last waypoint before updating the current waypoint to the next waypoint.
If it is the last waypoint, there is nothing more to do, so we set the _reachedLastWP flag and we’re done.
After this method has finished, we can see back in the Update() method that the MoveToNextWaypoint() method is called.
If only all coding tasks were this simple.
Again, we simply set our NavMeshAgent’s destination and the Unity AI NavMesh engine takes over.
Once we save our script and run the game, we can see the AI movement is behaving as desired!