Creating a Modular Waypoint System in Unity.

Esteban Ibarra
5 min readJun 7, 2021

We’ve finished giving our player the ability to stealthily walk throughout the building but our guards are currently mannequins and can’t properly protect the precious treasures in our museum! Let’s fix that! Today we’ll prepare our guard to start moving just like our player.

Just like our player, our security guard needs a navmesh agent in order to intelligently move around the floor:

Next, we’ll create a script to make a waypoint system he’ll follow around. Let’s call it GuardAI and add it to our guard:

As we’ll be using our navmesh system, be sure to include the UnityEngine.AI library:

And we’ll also be using List, which is a more dynamic Array system that allows you to add and subtract items and change the size of the list while the program is running. Something you can’t do with an Array. Take a look at the Boss Battle waypoints for another example! You may also need to include the library System.Collection.generic:

So the first step in creating the waypoint system is to create a List for a set of transforms that contain the x,y,z positions of where you want your guard to go.

Back in the editor, we now see a title called ‘Waypoints’. Perfect! This is the dynamic list, we’ll be adding to in just a moment.

First, we’ll duplicate our guard and place the duplicates where we want our guard to move.

Now that we have all of our positions, we can just delete everything but the transform. Since I was using a prefab, I had to unpack all the guards to not affect the original.

Then rename the waypoints for later.

You know what? This is just a demo. Let’s just use 3 waypoints.

Now we drag our waypoints into the list and we’re halfway there!

Back in our guardAI script, We’ll create a holder for our navmesh agent:

Now for our next step, no pun intended, let’s just get our guard to the first waypoint:

In the Start function, we check to see if wayPoints[0] is null. Remember this one script will be put on many guards so it’s good to error check. After making sure things are safe, we’ll use the SetDestination function that we learned to move our player to our first waypoint in our list, So let’s check!

Great! Now let’s expand on this so we take more waypoints into account!

Delete the entire if statement we just wrote in the start function, we’ll be replacing it with a more expanded version in the Update function.

We’ll create an int variable called _currentTarget to keep track of what waypoint we’re on.

In our update function, we check to see if our wayPoint list actually contains any waypoints (wayPoints.Count >0), and we also check to see if the list at the currentTarget also contains an actual transform. Then we’ll send our guard off to their first waypoint.

We check to the distance between our guard and the waypoint, and if it’s less than 1 unity, we consider that as officially arriving and so we check to see if the next waypoint exists and if it does, we add one to our _currentTarget variable. And since it’s in the update function, this check is always running so the guard will automatically move to the next waypoint! Let’s see if this works:

Awesome! our guard is walking over all of the waypoints except now stops at the last one with an error. That’s OK. We’ll fix that in a moment.

First, we’ll need a way of letting our guard know he’s going to move in reverse. We can do that with a boolean.

Then we make a slight modification to the code where the guard checks the distance between themselves and the waypoint:

So first, if we’re not going in reverse (which we’re not at first), we then check to see if the current target is at the last waypoint (you need to add -1 to the Count for it to be accurate, otherwise Unity will throw an out of range error) then _reverse will be true and it will check the next set of conditions. Otherwise, just add one to the current waypoint and be on your way.

However if the guard does hit the last waypoint, and begins moving in reverse, we’ll then check to see if they’ve hit the first target, if they do, reverse is false, otherwise, remove 1 from the _currentTarget and be on your merry way!

Ok, let’s see if it works!

Beautiful! We have a patrolling guard using a script that we can place on any amount of guards and with a little extra work in adding the guards animations, the final scene looks like this!

Tomorrow we’ll talk about giving ‘eyes’ to our guards so they can see and catch our tricksy little thief!

--

--