Enemy AI Series 1: The State Machine

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
ai is one of those topics that get a lot of game developers nervous because while at least some amount of AI is essential for most games it seems like such a difficult thing to tackle and so today we're going to be starting up a brand new series on this channel where we attempt to demystify all of the little things that go into creating AI and in today's Godot tutorial we're going to be learning about the engine that makes everything work the base on which everything else is built on top of and that thing is called the state machine so what exactly is a state machine when it comes to video games and especially with AI you're going to be dealing with a lot of different events that cause changes to happen in the game for example if you shoot at an enemy character who is patrolling a certain area maybe you want that enemy to panic and get behind cover or in other terms you could say that you want the enemy to transition from a patrolling state to a duck-and-cover state and if that enemies health gets really low then maybe you want them to enter into a berserk state where they rush after you and try to pummel you to death and you could have a bunch of different conditions where the enemy character does something different depending on what state it's in and so a good way to handle changing between all of these different states is with something known as a state machine which is what we're going to be building in this video so let's open up Godot and I'm going to be using this dummy model that I created in order to demonstrate the state machine now this isn't actually all that important if you don't have your own model that's fine you don't need to use it or if you've got a different model you can use that instead it really doesn't matter today we're going to be teaching more of a concept that applies to a lot of different things rather than a very specific scenario that being said if you want to include the model in your own project for whatever reason just follow the link in the description it'll take you to the download but if we go into the dummy scene you'll see that we have the model for the dummy itself and we also have a rake a sticking out of its chest and it's about 10 units long but I'll explain what that does in just a bit and if we dig even deeper into the dummy model you'll see that in my case I've got some animations attached to it if we click on the animation player and I've got three different poses for the character there is an idle state where he's just standing there's an alert state where he's alert and then there's a stunned state where he's clutching his head like as if a bomb or something went off next to him we'll get into this in just a little bit but now let's actually create the state machine so I'm gonna go back to the main scene for the dummy I'm going to right click on the main node for the dummy and I'm gonna attach a new script to it I'm just gonna go ahead and call it something like dummy state machine and then I'm gonna go ahead and click create so now we have our empty script and we're going to begin creating our state machine so the first thing I'm going to do is I'm going to write down a list of all the possible states that my dummy could be in and to do that we're going to use something called an enumerator or in Gd script it's called enum so you're probably thinking whoa whoa whoa what the heck is this okay so let me explain so unless you're an absolute beginner with using GD script and programming you're probably familiar with something known as a variable and all a variable is is really just like a little pocket in a computer's memory that stores a little bit of information so for example we could create a variable called number and we could store a value in it say lightened up number four similar to a variable is something known as a constant or in the case of Gd script Const constants are basically the same thing as a variable except that once you give it some sort of data that data cannot be changed unlike a variable so let's say we have a new constant also called number and we give it a value of two so now that we've given it the value of two as a constant it will always be two whereas with a variable right now it's four but we could write some code that changes it to seven or some other number and that is perfectly fine which is the reason why this is called a variable because it can vary and this is called a constant because it always stays the same if you really wanted to you can create a hundred different constant and that's totally fine maybe we'll call this one number two and that's given a value of seven we can create another one constant number three and give that a value of one or something like that it doesn't matter so now that we know all of this it's fairly easy to understand what an enumerator is because in a numerator is basically just a set of constants so for example instead of writing three different constants you could just create an enumerator you can give it a open close curly bracket and you can write number equals two comma number two equals seven comma number three equals one and so this is essentially the exact same thing as writing three different constants so really we can go ahead and just delete all of this because it's not necessary but there's actually another very useful thing that you can do with enumerators and that is you can actually use them to define different States for a state machine and so instead of giving a name and then giving it a value what you can do instead you can delete all this and you can write down the name of different states so for example in my situation maybe I want to have an idle State I'll have an alert state and I'll also have a stun State and we don't need to assign these things any values we can just give it a name and now that's the name of our States so now that we have our state's we need to make a way for our character to transition between the different states to do that the very first thing we're going to do is we're going to write var state equals idle and basically it's just going to keep track of what state our character is in in this case we want to start it off with idle this next part isn't strictly necessary but in my case I want to create a reference to the raycast that's sticking out of the characters chest because I want to use it as part of this demonstration so we'll go back to the script and under this line we're going to write on ready var raycast equals dollar sign raycast and I also want to create a reference to our characters animation player because I want our character to play different animations depending on what state it's in so again we'll go back into the script and under this line we're going to write on ready VAR ap equals in my case dollar sign male zero zero one export 1000 four slash animation player this is probably going to be completely different in your specific case so don't worry too much about this and so now we're ready to create our state machine and in order to do that we need to create a brand new function so under this code right here we're going to write func underscore process Delta this is our process function and it updates every single frame in it we're going to write match state and I'll explain what this does in just a second and inside of it we're going to write down all of our different states so we have idle : we have alert : and we have stunned : and so now we want to give instructions about what our characters should do when it's in a specific state so if our character is in the idle state inside of it I'm going to write ap play idle so if it's in the idle state I want the animation player to play the idle animation similarly if our characters in the alert state ap play alert and if our characters in the stun State API play stunned so here we have all of the different states that our character can be in and all of the different actions that the character will take if they're in a particular state so here we wrote match state and if you remember we created a variable called state and we set its state to idle what match does is equal match just like the name suggests whatever it is we set as our state so for example since we set our state to idle match we'll take a look at state up here it'll see that it's idle and it'll say okay we're just going to run whatever it is inside the idle State so if we change this to alert then match we'll take a look at that see that it's in the alert state and it will run whatever is inside the alert state and won't run whatever's in the idols date and the same thing for stunned if for example we created another variable of our other state and we set it to alert we could change the state to other state and in that case match will match whatever it is in other state not state but we're just going to go ahead and change this back to state and get rid of this so now if you run the game you'll see that our character is in the idle pose and there's really not much you can do to interact with it right now now let's make it so that this character will enter in two different states depending on various things that you as a character do so we're going to go back into the script and we're going to create a few conditions that will determine what state our character is in so in our process function we're going to add a few more things we're going to write if raycast dot is colliding state equals alert so if something is colliding with the raycast that's sticking out of our character's chest in this line right here then our character will be put into the alert state and if it's in the alert state then it'll play the alert animation we're also going to write L if input is action pressed fire so if we press the fire button in my case it's the left click on my mouse we're going to write state equals stunned so if we press fire it'll enter into the stun State and instant it'll play the stunned animation and then we want to write else so if none of these things are happening state equals idle so if the raycast isn't colliding and if we're not pressing the fire button then the character will default to the idle State now before we run the game I'm going to go into debug and I'm going to check the box that says visible collision shapes just to help visualize what's going on so now we're in the game and as you can see there's a yellow ray cast sticking out of our character's chest right now it's in the idle State and so it's in the idle pose but watch what happens when we move our character into the ray cast the raycast turns red it's colliding with something and our character changes its pose to the alert pose if we move out of the raycast then our character goes back to the idle pose and if we hold down the fire button our character enters into the Sun state and now it's in the stun pose if we let go of the fire button then it returns back to idle and with that we now have a very basic state machine which will serve as the backbone for all of the AI we'll be adding to the character in future videos now some of you may be wondering why we would even bother to create a state machine when we can get the exact same results with a bunch of if statements and in future videos on this topic we'll begin talking about the benefits of state machines and how they can make your life as a game developer a lot easier but until then thanks for watching the video and as always make sure to join the discord community for some awesome game dev discussion and if you like the video be sure to like it subscribe it share it bail it and comment it thank you have a nice day [Music]
Info
Channel: Garbaj
Views: 44,403
Rating: undefined out of 5
Keywords: godot, godot tutorial, godot3d, godot 3.1, godot 3.2, garbaj, how to make video games, how to program, how to code games, game dev, game development, game dev tutorial, unity, unreal engine, ue4, halo, halo ce, halo mcc, state machine, ai, artificial intelligence, game ai, video game ai
Id: RzUkBT7QwrU
Channel Id: undefined
Length: 12min 10sec (730 seconds)
Published: Wed May 27 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.