In the previous lecture, we had a look at what finite state machines were, and we set up an environment.
Now we're actually going to start coding for that environment and creating some states.
Alright, so back in our assets what we're going to do is create a new script, so create a C-sharp
script and this script will be called Game Environment.
Open that up and then inside we're going to create our singleton.
So this won't inherit from mono behavior and it's going to be a public sealed class like we've made
before.
And then we want to create our lists to hold those check points.
So first of all, let's create a private static game environment instance for our singleton and then
a private.
List of game objects.
Check points equals new list of game objects.
And then a public call for that public list game object.
Checkpoints.
Get.
Return checkpoints.
Okay.
We don't need a start and we don't need an update, so we'll get rid of those.
And then all we need in here is our singleton.
So we'll put in a public static game environment.
Single Chin.
Get.
If instance equals null, then we will create it.
Instance equals new game environment.
And then we will populate those checkpoints for the actual instance itself.
So instance checkpoints with the capital.
Dot add range and that range will be game.
Object.
Find.
Objects with tag the plural one and we want checkpoints.
The tag that has the capital C just checkpoint, not checkpoints.
And finish that off.
Okay.
And then we will return the instance and then make sure we have enough closing brackets for everything.
Three of them at the bottom there.
That's your game.
Singleton, that we can now use to grab those checkpoints.
And when we start creating the states, as you'll see in a moment, and the state classes are so nice
to have a singleton that you can call upon.
You don't have to pass it around between everything's okay.
Time to create our base state class.
So in the assets right click create C-sharp script.
Let's call it state, which makes sense.
Let's open that up in our editor.
And it is again not going to be a mono behavior now it's going to have these libraries we've already
got at the top, but we're dealing with the nav mesh.
So we're going to need to include the unity engine dot AI system.
All right.
So we've got our class now.
Let's get rid of the methods already existing in there.
So the first thing, let's create a public enum for the state.
And in here you want to list all of the possible states and you can add more later on.
We are just going to put a few obvious ones in for a NPC guard so they could be in an idle state, a
patrol state, they could be in pursuit.
So pursue state, they could be attacking or they could even be asleep.
Next, we'll have another public enum, which will be our event.
So this will tell us whether we are in enter, update or exit.
So where we are in the running of the particular state now in this state, we're going to bring in a
whole bunch of values that are specific to our actual game and the way we've got it set up.
But first of all, we need a public state and let's call that name.
So this will record what the name of the state is.
Then we want our protected event for the stage, which is one of these enter update or exit.
And then we're going to have.
Protected game object NPC a protected.
Animator Adam because we're dealing with animations as well.
Protected transform for the player.
We've got a god that we're creating.
So the guard needs to know where the player is so that it can face the player and know whether it should
be shooting or chasing the player, depending on the distance.
And then also a protected.
State.
Which will be our next.
A date like that.
This state is not the enum, which is this one up here.
So the name is based on the enum and this next state is the state that gets to run after the one we're
currently running.
So if you're in idle and then you want to go into patrol, then the next state would be pointing to
a patrol state.
All right, great.
Okay.
Some other values we need for the actual I let's have a float this distance and we will set that to
10.0 if float viz angle equals let's say 30 degrees and a float called shoot distance or dist, which
I will set to 7.0 f.
Now what these mean is that when the player is within a distance of ten from the NPC, then the NPC
should be able to see it if it's facing within 30 degrees of its line of sight.
If the NPC gets close enough within a range of seven, it can then actually go into an attacking state.
We'll get to that logic in the next lecture.
Let's continue by writing the method or the constructor, I should say, for this particular state.
So public state, it's going to take a game object which will be the NPC, a nev mesh agent, agent
and animator.
And and a transform for our player.
Then what we do with all of those.
So we actually sit them in here.
So NBC equals and Pixie Agent will equal the agent we pass through.
That agent shouldn't have an underscore in front of it.
Then we're going to have an atom which equals underscore score annum.
Stage which will equal event.
Dot enter.
And then player equals on the score player.
Now I've just noticed that I haven't declared agent let me finish this constructor and we'll just go
back at the top and add that in.
So a protected nav mesh agent called agent.
All right.
Now under there, we're going to put in the skeleton code for each of our different stages or phases
as we go through the state.
So these will be a public virtual void.
Enter.
Stage equals event dot update.
Now the reason.
This is the.
Enter.
So this.
This should run first.
When you come into a state and when it does it then sets the stage to be whatever's going to be next
so that it will know later on in the process that that's where it's going.
Public virtual void for update.
And then this stage will equal event update because once you're in update, you want to stay in update
until update actually throws you out and then public virtual void exit that will then set the stage
equals to event dot exit so it knows what to run and clean up after itself there.
Then finally, we need a public state process, which is the method that will get run from outside and
progress the state through each of those different stages.
So if stage equals event do not enter, then we will run the enter method.
If stage equals event dot update in capitals because that is our enum value, then we're going to run
update and then if stage equals event dot exit, we're actually going to call the exit method and we're
going to return the next state.
Notice that this particular method returns a state.
So now if we're not returning the next state, we'll just do a return.
This so that we keep returning the same state.
And you'll see where this helps progress to the next state and the next state in line.
As we go through now, we will create an idle state and a patrol state so we can actually get our NPC
doing something so that you can see this working.
Now I'm going to create my states that inherit from the base state class in this dot csv file.
Better practice would probably be to have them in separate CSS files, but because we're sort of constructing
this as we go and going back and forth between code and what not, I'm just going to have the whole
lot in the same place just to make it a little bit easier for us so that we can see it all and we'll
come back and keep putting that together in the next video.