Modular AI Waypoint Movement in Unity

Make Your Minions March

Micha Davis
3 min readMay 7, 2021
Pika up the pace!

The idea of orchestrating AI movement can seem daunting at first. Sure, we could write a script for each enemy telling them how to to find each of their waypoints, but what if I have hundreds of Pikachus… er… enemies to script? And what if an enemy has hundreds of waypoints? Can you imagine 100 if/elseif statements on each of 100 different enemies?

That’s too much work. Whenever there’s too much similar work, it’s time to modularize.

So, what we want is a generic script that can be applied to all the enemies and can accommodate any number of waypoints. Let’s talk through that problem.

Firstly, to accommodate any number of waypoints we need a List of waypoints. Also, an enemy might have no waypoints if they are stationary, so we’ll need to null check that list before we do anything else. If we do have waypoints, we want to set our NavMesh Agent destination property to the position of the next waypoint in the list. And we’ll also need a way to index our list so that we actually know which one is next. Finally, we’ll want the enemy to pause at either end of their patrol route before going back along the route to the other end.

Here’s the pseudo code to describe all of that:

And for the waiting coroutine:

So, in order to get the coroutine to behave properly, you can see we will pause the action with a boolean switch based on whether the enemy has reached the target waypoint. If that waypoint is the first or the last, we’ll wait, and then flip that bool switch back to false so that the incrementing or decrementing of the waypoint index can occur.

Now let’s pound that out into code. First, variable declarations:

The list is public, and can be populated in each enemy’s Inspector window in the Unity Editor.

Then, in the Update() method:

One thing I had to modify from my pseudo code was checking if the currentTarget == wapyoints.Count, because of course lists begin at index 0, but List.Count returns a nonzero integer. So, that has to be waypoints.Count -1 or else we’ll get an out of index error.

And now the coroutine for waiting:

There. Now, no matter how many waypoints an enemy has, they will patrol through them all from first to last, and then last to first, pausing at each end of the route.

The results:

Glorious.

That’s it for today’s article. Join me tomorrow when I’ll be going over my overall progress on this project so far.

--

--

Micha Davis

Unity Developer / Game Developer / Artist / Problem Solver