Make an Action RPG in Godot 3.2 (P9 | Attacking Animation + State Machines)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Hey, heartbeast is awesome. Great at explaining stuff. Got me into gamedev with his gamemaker rpg series.

👍︎︎ 5 👤︎︎ u/hyrumwhite 📅︎︎ Mar 31 2020 🗫︎ replies

I <3 HeartBeast. His GameMaker background is helpful for me as I am transitioning from GM.

👍︎︎ 2 👤︎︎ u/bitcrow 📅︎︎ Apr 01 2020 🗫︎ replies

I didn't know about blend states. will have to read up on them later.

👍︎︎ 1 👤︎︎ u/Fibreman 📅︎︎ Apr 01 2020 🗫︎ replies
Captions
good morning afternoon or evening wherever and whenever you are my name is Benjamin and welcome to part 9 for our Godot action RPG series in this video we're going to be adding the attack animation to our character and implementing a simple state machine let's get started first click on your character scene here and click the little scene icon that will open up our character scene we can zoom in just a little bit and we'll need to open up our animation player because we need to add these attack animations so we'll come to animation do new we'll do wait what order did I do these in down left right up down left right up so let's do in the same order well maybe it's actually just out there organizing them alphabetically but we'll do attack down and we'll click on our sprite here and we'll come to our where is it frame and we'll go well we're gonna need to stop this from playing so we can and this is actually something that came up in the previous video you can uncheck active right here and then inside of our process right here or inside of our script right here we can actually bring up the ready function and I just call animation tree dot active equals true so what that'll do is it'll make it so that our animation tree isn't active until the game starts and so then our animation isn't constantly playing so we'll come back into here and well now we can actually flip through our frames we won't attack down here we go here's the first frame so we'll key this frame come over one go to our next frame and key key key and so that is how many frames are we here got one two three so we want point four four this animation will save do a new animation attack left it'll be point four as well we can come back and find our attack left key this frame will come over one go up one and then Kiki and key save add an animation we'll do attack right I guess 0.4 where's our attack right here we go key this frame got to come over one key key key save add a new one we'll do a tack up wait did we already do a tack up I don't think we did down left right up I think it just puts them in alphabetical order anyways I don't know it doesn't really matter and come back so we need up which is right here okay there we go now we should have attacking in all of the different directions so we just need to set up our state machine and I'm gonna do a simplified state machine you can get a lot more complicated with these and depending on how big your game is you may want to look into some more complicated si solutions using different nodes for States and stuff like that but for this game it's going to be a fairly simple little project so we're going to wear our character is going to be fairly simple so we're going to use a match statement in order to set our our states so we'll come up here and we'll create a new variable and we'll call this state and above this we can create an enum and we'll call we'll set our state's we'll have move role and attack and we're not going to set up role yet but we will be setting up attack but we'll just put it in here so an enum is short for enumerator or enumeration and what it does is these these are kind of like variables except that they can't change so I guess they're a little bit more similar to constants in that way but they are automatically created with values so this is 0 this is 1 this is 2 and so it just it just makes sets each one of these to a specific value like 0 1 2 these are commonly used for like dates like if you have the days of the week Monday Tuesday Wednesday Thursday Friday Saturday Sunday you might want to have an enumerator to store those values so that you're not using numbers like 0 and 1 you're actually using words but really they just represent numbers at the end of the day cuz they just need their own little IDs so our state variable here will set this equal to move and then inside of our physics process right here we'll set up our match statement and this match statement will basically determine which code to run so with a with a state machine let's open up paint.net real quick so we can explain this really well so for a state machine you have different chunks of code okay so let's say we have three chunks of code here and each of these bits of code represents one of our states so this one could be move this one's attack and this one could be roll okay they each have their own bit of code inside of a state machine only one of these pieces of code is ever run at a single time and the benefit of that is that your your debugging and your when you have errors and stuff and have to try and figure out what's going wrong in your code these these sections of code are segmented off so if you have an error when you're moving then you're gonna look in your move state right you're not gonna look into your other states and these bits of code have transitions between each other so let's say we press the space key that would transition from our move to our attack or if we press another key that would transition to roll so this could be space here maybe this is just that a key or something and that transitions to these two other states well these states like attack and roll for example they have to have some transition back to the move state so for attack it's likely going to be when the attack animation is completed so once the animation is over we'll transition back into our move state right here that's how states are set up they're designed so that only one piece of code is ever run at a time and for us we're going to this is this code right here is our move state right here so we can actually move all of this code into its own function so we'll come down here we'll create a function we'll call this move state and [Music] we can just copy all of this code right here do control X paste it into this function right here move state and then once once we've done that up here in our physics process we can call move state like this and that will run this code we do have an issue however here which is where we need Delta and so we'll have to pass our Delta into this function right here this function because we're using Delta right here but we only have access to it here in the physics process so we can pass Delta into our move state like this okay and if we do this essentially our game hasn't changed at all right this game functions exactly how it did before nothing has changed the only thing that we've changed is how we organize our code because we've moved all of this code into its own little function here so we want to be able to change States like I said and so we'll create another function here called attack state and it will take Delta two will pass Delta into it as well and for now we'll just call pass which doesn't do anything that line of code just does nothing and then up here we can use our match statement so m80 CH match and you want to match you want to tell what to match and we're going to match our state and we'll say move so if our state is equal to move then run the move state code if our state is equal to role we'll just pass for now we'll be implementing that later if it's to attack then we'll call attack state will pass in Delta so match match statements inside of Gd script work very similar to switch statements inside of other languages now there are some differences the main difference is that this what you're matching your case here can actually be very a variable which was switch statements my understanding is you can't do that so there are some slight differences but functionally they're very similar and so we're just going to kind of pretend that they're the same for now because this works exactly like a switch statement you just don't have to have case in front of each of these you can just tell it what to match so what this says is if match is equal to if if the state I should say matches move then do this if the state matches role then run this code if the state matches attack then run this code and you can see that you can never actually run more than one of them at a time because the state variable is always going to be equal to only one of these things it will never be equal to multiple so once we've set that up we can actually we can actually start setting up a transition remember when we talked about our transitions so we needed some sort of a key to transition to our attack state and this is a good time to briefly introduce the input map settings inside of Godot so if we come up to project and go to project settings and then we come over to our input map you can see all of the different actions that Godot has set up and the ones that we've been using and you can add your own actions up here as well so we're using UI right left up and down right some of you have been asking me how you would set up the WASD Keys well you can just come to you I left here add a new key with a little plus button and then press the a key for right here we can do the same thing press the D key and up do the same thing press the W key down same thing press the S key and now you've got WASD working already so we'll set up an attack action here and we can give it whatever key we want to so I'm going to give it the space key and also for a WASD I'm going to give it the J key there we go so J and space can both be used for this new attack action that we created so how do we use that action well we come into our move state right here and we can say at the very end of the code here we can say if input dot is action just pressed so that means we just barely pressed it and we didn't hold it down or we could be holding it down but it won't run multiple times it just runs once so if we just press the attack key then we say state equals attack right what that will do is set our state variable equal to the enum that we created for attack and then our match case will no longer run our move state it will now run our attack state in the physics process we save the game and run it we'll see that we can move around the minute we press the space or the J key we can no longer move we're stuck and the reason is because there's actually no code inside of our attack state so it doesn't do anything well let's start by having it play an animation that seems like a pretty good start right animation player don't play well that's not really what we want right because then we'd have to tell it which direction to play for our animation so that's not what we want well well for now let's actually just do that we'll just show it so we'll do attack right okay and run the game and now if we press the key it tries to play the attack right animation but then it stops and kind of switches back to our normal standing well that's because we need to set all this up inside of our animation tree here right we have a we have an idle and a run but we need a new blend space 2d for attacking and we can just have a transition from our idle to our attack and then back again and for our attack stick it right here I guess for our attack we'll come in to edit it and we'll add point 1 on the Y to both sides we'll start adding in some points here add an animation attack left add an animation attack down remember that up is down in here add an animation attack right add an animation attack up ok so we set up our animation here we can make sure that this is working by turning our animation tree back on and then moving around inside of here selecting this bit here and moving around oh we actually have to come back to our root and play it so that we can see it and come into here well it might need to loop to don't know if we set up a looping on it and that's why it's not playing here if we come back into our animation player turn on loop for all of these that looks like a special ability right there okay so I set loop on them all come back into our animation tree and so yeah we want to make sure inside our blend equal to the little dots again now we get now we're getting the attack setup right so that's important to make sure that you've got this setup right because can be hard to tell and it's really easy to forget the little blend dots here okay so we can turn off this now because we know that it's working properly so we can uncheck active on our animation tree and we can come back and we can play the Eifel again which will put it as active and then inactive real quick just to get it set up then when we come into here we need to make sure that in our move state we're setting the blend position for attacking so we're gonna copy this line and we're going to set the blend position for attacking and you might be asking me or thinking in your head right now well why don't we put this line inside of the attack State the reason we don't want to put this line inside of the attack State is because well there's a couple reasons first of all our input vector isn't actually inside the attack State we don't actually have access to it and second of all we actually don't want the player to be able to change the direction of their attack during the animation that could look kind of weird it's like a mid animation if they could change once they press the attack button they're committed to attacking in that direction that's how we're setting it up and so we're setting the blend position before they press the attack button and then the minute they do press it it will remember this the parameter the blend position will be the same as it was when they were moving in the attack State so now we can set up our animation State DOT travel and do attack right here so what will happen is inside of our animation tree if we're in the run it will actually transition to the idle and then to the attack state so it's going to it's going to find the easiest path to get to our attack animation so if we run the game and we attack you can see that it actually starts the attack so that's pretty good we're making progress now it doesn't finish though we don't actually get any sort of ending to our attack right we can't transition back into the move state so we need to have some way to tell it that the animation has completed that the animation has finished and well so there's a few different ways that we might go about doing this and the way that I've set up to do this is with a little function so we'll we'll start with this method we may end up changing this later kind of refactoring our code but this is a good starting point so come into your attack animations and on the very last frame we can add a new track over here so we can manually add a track and you can do a call method track and we'll call a method on the player note so what this does is it'll say at this point at this frame you can have it call a certain method so let's create a new method here called attack animation finished and in here we'll just say state equals move so when our attack animation is finished we transition back to the move state so now down here in our animation we can right click to insert key and we can find our attack well it's not finding it there insert key attack animation finished here we go so you can see now at the end of this animation it'll actually call this function that's for attack down so we want to set it for all of them now add a new track call method track player right click insert key attack animation finished right add a new track call method track player right click insert key attack animation finished and then one more time for up the exact same thing here tech animation finished and save we can run the game and now once we're done we transition back to the movement state we've got a few weird things going on here right so the first weird thing is that if we're moving and we do our attack we get this kind of awkward this awkward bit where we slide forward after attacking right that's happening because we're not we're remembering our velocity we might want our attack state to set our velocity equal to zero so it no longer remembers the velocity during all right during our motion okay the other weird thing we're getting so that solves that problem the other weird thing we're getting is this little flicker at the end of the animation you can see it like starts playing the animation again and so we want to be able to fix that the way that we can fix that now is by set by turning off loop on all of our animations because we don't actually need the attack animation to loop I set it up on loop so that we could see inside of our animation tree so that we could watch the attacking to make sure I was working but we don't actually want the attacks to loop and there you go now I've got a nice follow through with the animation we can attack and we've got a simple state machine setup okay so let's talk about what we did here we added the animations to our player we set up our new blend space for the attack and we set the animations to loop so that we could make sure all of that was set up properly and working then we created two new variables a state well we created one new variable which is a state and we created an enum which had the different states that we're going to be using we moved our movement code into its own move state function and we set up our own attack state and a little animation finished function for that when the attack was over and then inside of our physics process we set up a match statement using our state variable so that we could make sure and only run one of our states at a time now you could in this case you could say if state equals move then run the move state LF state equals role then run the role state which is nothing right now l if so you could do this as well this actually works the same way as a match case but I did want to introduce the match case to you guys so that you could learn about it and how it works because this is a little bit cleaner it's a little bit less to write and set up then using an if-else or an if Elif Elif statement but functionally in this case they actually work the same so if you're having a hard time grasping this logic that's another way of doing it using an if else if else if statement you can set up your state machine like that so that's going to be it for this video we learned oh yeah we also learned about input maps and how the input map works which i think is a good thing to learn about now you've got multiple controls set up so I hope you guys enjoyed this video this series has was made possible by the Kickstarter backers for my one bit Godot course I'll put a link to that in the description if you guys did enjoy this video be sure to give it a thumbs up give me a comment down below if you have any questions and subscribe to my channel and I will talk to you all later
Info
Channel: HeartBeast
Views: 102,143
Rating: undefined out of 5
Keywords: Godot Engine, Godot 3.2, Godot 3, Tutorial, Series, Action RPG, RPG, Pixel Art Game, Indie Game, Game Development, Learn gamedev, Gamedev
Id: 0nd1zNiy0C4
Channel Id: undefined
Length: 25min 44sec (1544 seconds)
Published: Mon Mar 30 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.