Creating an Enemy State Machine in Unity 3D

AKA Directing Zombie Traffic

Micha Davis
3 min readJun 12, 2021

I’m making a simple 3D zombie shooter, so OF COURSE we need zombies. It may seem strange to think of zombies as intelligent, but we need to construct some intelligence into our zombies so they know what to do. They won’t eat anyone’s brains unless we make it happen behind the scenes.

For this, we’ll use a common solution: a Finite State Machine. This is essentially a switch statement paired with an enum, that… well… enumerates the states.

I haven’t written about enums yet in these articles, so let’s break it down.

The Enum

My past efforts at enemy AI states have been done the long way, and without thinking of it in terms of differing states. This time, the Enemy script is going to be far easier to follow and debug than that tangled mess. And it all starts with the enum.

An enum is a way to create a prefilled, ordered list of strings and then refer to those strings either by number or name. This gives you a ton of flexibility, and can actually allow you to do some pretty interesting tricks.

So, in our case, we want to define some behavior states for the enemy AI to follow. We need:

  • an Idle state (for when no brains can be found)
  • a Chase state (for when brains are found but they are far away)
  • and an Attack state (for when brains are nearby, but inside someone’s skull for some reason)

And then we want to be able to switch easily between states depending on what’s going on in the game (more on that in the next section).

The syntax for our enum will be the following:

Here you can see we are defining three states. What we don’t see is the enumerating — but it is there. Idle is state 0, Chase state is 1, and Attack is state 2. You can expand this as needed if, for example, you needed a patrol state that kept your enemies roving for brains.

I’m also declaring a variable of the type EnemyState called _currentState so I can use the enum values later in the switch statement.

Speaking of…

The Switch

This is where the magic happens.

We’ve covered switch statements before, so I won’t hold back the code:

So, the Update() method is constantly checking the _currentState. If the state is changed, the enemy behavior will immediately shift. When the game starts, my zombies will stand still, drooling mindlessly as they use the LookForTargets() method to scan for brains. Then, when brains (a Player) are detected, the state changes to Chase and the zombie spends every frame running CalculateMovement(). If the player gets close enough, the zombie enters the Attack state. At this point, the movement code is unreachable and its only option is to Attack() until the brains are freed from their skull (in which case we return to Idle) or the brains run outside the attack radius collider (and we return to Chase).

That’s it! I know I didn’t go into great detail on attacking or moving, but I’ve gone there in past articles, and didn’t want to repeat a lot of old territory. The gist is here, and everything you need to create your own Finite State Machine is in your hands.

Tomorrow I’ll go over Inverse Kinematics for the Player.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Micha Davis
Micha Davis

Written by Micha Davis

Unity Developer / Game Developer / Artist / Problem Solver

No responses yet

Write a response