Okay.
It's time to start getting a little bit of AI behavior built into our NPC and we're going to do that
in the States so we don't actually have to touch the AI script at all.
We'll go into the States and just transition different states to change the behavior of the NPC, which
is what they're all about.
Let's go right to the top of our states code into the base state.
What I'm going to do in here is add a few little helper methods.
First of all, the logic we're going to use is can the NPC see the player?
So we're going to use a sort of simple line of sight calculation, which means that the player has to
be within a certain distance, but they also have to be in front of the NPC, at which point the NPC
can then decide whether he's going to chase the player down or whether he's going to start shooting
at the player.
So we will have it so that it has to be a little bit closer to the player in order to shoot, which
means that you can run away and have the embassy actually run after you until it gets into the shooting
range when it will switch back to shooting.
So it's a little bit more dynamic than have it just shoot at you want to get it to move around the map
and follow you.
First of all, let's build these two methods.
So first we want a public bool.
So it's going to return true or false and it will be can see player.
So we're just asking a very simple question can the NPC see the player?
Now, in order to do that, we have to calculate the distance and also the angle.
So let's start with the vector three.
That will be a direction from the player dot position.
Minus the NPC transform position.
So this is giving us the vector from the NPC to the player.
Okay.
Then we can find the angle.
Float angle equals vector three dot angle built in unity math using the direction vector and the NPC
is trance form dot forward vector.
Then with that angle, we can figure out whether we are within the line of sight.
Okay.
So the if statement is going to go a little bit like this.
If direction, which is that vector between the player and the NPC dot magnitude, which is the length
of that vector.
So the distance between the player and the MBC is less than vs dist.
Remember, that's our float we created very early on up the top.
In fact, we're going to use all of these in this little set of methods.
So we've got our visible distance at ten, our visible angle at 30 degrees and our shooting distance
at seven.
And you can change those and play around with them as you like to get different behaviors.
Okay, so there's our visible distance and we also want the angle to be less than the viz angle.
So the visible angle is set to 30 and we're going to be finding the angle between the direction and
the forward vector of the NPC, which will be half of its total visibility.
So if you want like a 60 degree field of view for your NPC, then we're just give it a viz angle of
half of that, which is the 30.
Now if that if is correct, then we can say that we're going to return.
True?
Yes, I can see the player.
Okay.
Just fix up these brackets and we're done with that one.
Oh, of course.
We also need to return false as our fallback that we can't see the player.
The other method that will add just after this one will be to determine if we're close enough to attack
the player so we make it a public ball again, can attack player.
And then inside of here, what we're going to do is get our direction vector again so we can just copy
this one here.
And we're simply going to check the length of it.
So if direction magnitude is less than the chute, distance or dist in this case, then we will return.
True.
Otherwise, we'll return.
False.
Okay.
So I think I just lost a bracket in there for the end of the class and we put that back in.
Okay.
So these are the two methods that we're now going to use further down in other states to determine if
we should then start following the player.
Now, we don't yet have those states, so we're going to add them at the bottom.
So scroll right down to the bottom or open up a new file if you're putting all of these in separate
class files.
And let's start with pursue.
So public class pursue.
And that will be a state.
Then the first thing we need to do is our constructor.
So public.
Pursue.
And it's pretty much going to have the same stuff as our other states, which is this here, because
we need to pass through all of these details.
So let's go and add this in.
Like that.
Okay.
Then inside of here, we're going to set the name.
So the name will be equals state dot pursue.
Not that state.
They're like that.
Then we need agent speed.
So agents speed.
In this case, when he's chasing after you, let's make that five.
So and actually be running rather than walking when he's pursuing you.
So you do need to make it a bit bigger and then just make agent dot is stopped equal to false.
All right, now let's get into our enter.
So public override.
Void.
Enter.
And it's going to.
Set the animation for running so animate set trigger.
He is running and that's all we need to do inside of the enter the method that's going to do most of
the work will be update in this case.
So public override void update.
And it will have not the update as we've learnt before.
Let's just get rid of that because what it doesn't isn't any use to us agent set destination and this
will set a goal position for the agent for the nav mesh stuff.
So it's player dot position which will set it.
Then we're going to say if the agent dot has a path, which means it's actually following the player,
we're going to test if we can attack.
So we're in pursuit and then if we're close enough, we want to actually switch over into an attack.
So if can attack player.
And then inside of that we will put next state equals new attack.
And that again we'll have our NPC agent Adam and player passed through and then stage will be equal
to event.
Dot.
Exit because we're now finished with this pursue state and we want to then switch over into the exit.
Now, if we can't attack the player, then we go.
So going to test if else, if we can't see the player, so not see the player.
Remember that seeing the player switches in to this state and then once we can't see the player any
more, we want to switch back into the patrol state.
So next state, in this case, if you can't see the player, will equal new patrol.
Again, we want to pass through these things.
Let's just copy them from up there, bring them down here.
And again, we're going to stage equals event, not exit like that.
So that is our update.
Let's just close the brackets off for the has path.
Now, why am I checking for this has path if we've obviously set a destination up here?
Well, with the nav mesh system, what happens is you can set a destination, but the nav mesh processing
itself may not have yet taken place by the time you get from here to the next sort of lines.
So you want to least wait one update until it comes back into here again to figure out if you have a
path and then figure out the attacking and stuff.
Otherwise you get really strange behaviour and it's just a thing that the nav mesh does and the way
the nav mesh does it, you will have set up something for the nav mesh and told it to set a destination
or work out a path or do something with the agent.
And then you'll be trying to do stuff immediately after in your code and it won't work.
And that's because it's got to run stuff in the background before it's in a state of sort of readiness.
And this here is just testing for that.
All right.
So we've now done our update.
Let's put in our exit and that will be public override, void, exit.
And when we exit we're going to reset the trigger for our is running to just make sure that it's not
hanging around on us.
Then our base exit.
So that's all done for the pursue.
Right following that, our final state for now is a public class attack.
State.
And this is the attack that we're using up here.
If you can see the player, we want to go into attack mode.
Okay.
So what are we going to have in here?
Well, the NPC in this case actually has to follow the player or turn and look at the player.
If you'd like it to as it's shooting.
So we're going to put a float rotation speed value in here equals put to F so we can rotate around.
We're going to grab the audio source that's attached to the NPC.
Now, this is the case I mentioned in the previous lecture where I'm going to have a get component to
get the audio source, whereas you probably would be better off passing it through rather than sort
of getting it every time an attack situation comes up.
But this is the way I've done it.
So public attack.
Now we need all of our bits and pieces that we had before.
For these, let's go up to the pursue and just grab all of that because we're using that again, put
it into our attack and then let's name it.
So name equals state dot attack.
And shoot is going to equal the PNP secret component.
For the audio source that's attached to UG, which is a shooting sound.
Okay, so that's all we're doing inside of that attack.
All right.
Next, we need the old use rules again.
So public override, void, enter and.
Public override.
Void.
Update.
And the exit.
So public override, void, exit.
When we enter this state, first of all, we want to set up a shooting animation.
So animate set trigger.
Is shooting.
Again Agent Dot is stopped is going to be sit in this case to true like we do in this case we want to
stop the agent because they're attacking they've come out of the pursue.
So they're actually the agent is walking along a path towards the player.
But as soon as it sees the player, it has to stop that path.
So by putting agent is stopped equals true will actually sort of stop it in its tracks and then it can
start shooting and that will prevent it from following you while it is still shooting.
Now we also need to start the shooting sound so we go shoot play and that will start it for us.
Next, we're on to the update method and we'll have to do that in the next video because I'm well,
I'm running out of time, so I will see you in there.