If you've worked with character animation or non-player character behaviors in a game, chances are
you have implemented states at some time, or other states allow game objects to take on different behaviors
when required, making them look like they are controlled by a completely different class.
Unity makes use of states in the mechanism system.
In the animator, you can create a simple graph of states from individual animations and define how
to get from one to the other state.
Finite state machines used in games are the embodiment of this design pattern.
A finite state machine is a conceptual machine that can be in exactly one of any given number of finite
states at any time.
A finite state machine is used in the field of artificial intelligence to define, among other things,
the behaviors of computer controlled characters.
It is represented as a graph with nodes that represent the states and transitions that define the path
from one node to the next.
Once a state has been entered, the NPC stays in that state until a condition on the transition is met.
Here we have a finite state machine for simple guarding behavior.
If the NPC is in the patrol state, it will continue performing the associated behaviors until a condition
is met on any of the transitions exiting the state.
In this case, it is waiting until the player is a distance less than 20 away.
Once that condition is met, the NPC transitions into the Chase State.
Any state in a state machine has three processes that it runs at different times.
It has an enter, it has an update and it has an exit.
Enter runs as soon as the state is transitioned to the state, then enters the endless loop of the update.
Update continues to run until the transition out of the state is triggered.
At this point, before leaving the state, the exit method is run.
For example, an NPC that is transitioning to the patrol state on entering will need to set the appropriate
animation as well as determine where the waypoints for the patrol are.
During its update, the NPC will simply walk from one waypoint to another, constantly checking when
a waypoint has been reached and then looking for the next one.
Something in the update must cause the exit to fire.
This could be something as simple as the NPC deciding to have a sleep.
The walk animation is stopped and the NPCs transition into the next state that takes care of the new
behavior of sleep will begin.
A state machine can be as easy to implement as an if statement.
For example, let's say you have an NPC that you want to be in either of two states, idle or walking.
This would be easy to handle in an update loop, and you've probably done this yourself before.
In fact, the code that you see here is way too verbose for what you actually want to do in such a simple
task.
But it is pulled apart to illustrate how states work.
So first of all, you have a state flag that records the state that the NPC is in.
Now, in this case, I've used a string, but you could easily have an integer or even use an enum which
would make it more meaningful.
Now you could use a key press to indicate whether you want to walk or whether you want to be idle,
which would then set that state flag.
Later in the update loop.
We test for the state.
So as the state is changing, if it wants your NBC to be walking, then it's going to play a walking
animation and actually translate the character in a forward direction.
Whereas if it's idle the state, then you want to play the idle animation and you don't want to move
the character.
If, however code outside this class is able to set the state to dead, the key presses inside the update
would overwrite this and you would have to deal with it by a little bit of refactoring which might look
like this.
Note how we are testing for the state being dead inside the update before doing anything else.
Okay, so this isn't too messy, but once you start adding lots of other character states and have them
mixed together, riding a state machine in this format gets way too over complicated.
Therefore, the state pattern comes into play where a state is defined as a contained piece of code
that deals with all of the behaviors and only the behaviors that belong to that particular state.
Instead, we are going to write our own state based class that all other states will inherit from a
state records the type of state it is, which will entirely depend on the type of state machine you
are writing.
In this case, it will be used to build a state machine for an NPC guard who will patrol an area and
pursue an attack approaching players.
Remember the three phases of a state?
Well, they are enter, update and exit.
The phase will dictate which method to run.
You can see that there are methods for each of the stages and the base methods update the stages accordingly.
Last but not least, there is a process method.
This is called from outside of any state and it determines which method inside the state should run
at any time based on the set stage.
Through the use of this base class as a template for all states, we can be sure to keep the code related
to each state compartmentalized from other NPC behaviors.
It really is a quite clever design pattern.
Okay, enough of the theory.
Let's start building this thing once you get some code together and start creating more.
More states inheriting from that base class.
You'll see just how powerful this design method is and how it will make your life creating AI behaviors
in your characters so much simpler than having to juggle which state they're in and which animation
is playing and which animation is not playing, which cares press and all this sort of stuff, because
they can get really, really messy very, very quickly.
Right?
So open up a new unity project.
Now I want you to bring in the starter file that is attached to this lecture as a resource.
Just be aware that when you first bring in that unity package, unity will want to restart itself,
and that's because the controller has the new input system on it.
So just let it restart itself so that it brings in the correct packages.
And then once you've done that, you might get a few errors that come up in the console.
You might not, but if you do, just like ignore them, okay?
Or just clear them, they won't cause you any future issues because most of the standard asset stuff
that's in here from the old standard assets, that does cause a few issues because the code has been
deprecated.
I have actually taken that out, but I can't promise I didn't miss anything though.
I've just brought this in myself and I'm not getting any errors, so just be aware of that.
As long as they're not read errors, you're pretty good to go.
Now I've got the navigation tab up here as well, and if you've opened up my project, I believe you
will get that as well.
If you don't just go to window and I navigation to open up navigation, go to the back tab and then
just click on Bake.
Now that will re bake the surface of the nav mesh showing you the walkable areas in blue.
And you can see here that the structure is excluded and the area around the trees as well.
Now, ug, who is our God?
Let's get in a little closer to him.
Zoom in here.
There he is.
Okay, so he is guarding our structure.
He's going to go on patrol and he has a nav mesh agent component attached to him, which will do all
the work for us.
For him moving around.
He has an audio source for the gun shooting and his animator is all set up for you if we have a quick
look at that animator.
So let's just double click on the UG animator and just open this up.
Press F to center it.
You'll see that there's a idol so there's a rifle idol.
There's also up here, a rifle walk, rifle run and a rifle firing.
And there's a few other things down here that will get to a little later on.
This in itself is a state machine because it's animation states, and these are the transitions that
trigger between them.
But we're not writing this.
So this is just the animation one, but you'll see if you click on any of the transitions.
So for going from Rifle Idol to rifle walk, then you have to trigger the is walking condition and we
will do that all in the code so you don't have to set that up.
It's there ready to go for you, but there's no code currently on UG.
The first thing that we're going to do is we're going to write a singleton class for the game environment
because like our previous projects that we've created, there are some checkpoints set out on the surface
and you'll see them in the scene if we go up here.
And if I just click on all of them, there's five of them in total and there they are.
So they give us a circuit to go around.
Each checkpoint has a tag of checkpoint with a capital C.
Okay.
Well, that's pretty much the whole set up of this environment, which has taken up a whole video to
get used to.
So investigate this a little bit more if you want to see how it's all set up with the animator and all
those sorts of things.
When we come back in the next video, we'll actually start programming our finite state machine.