Using the animation state machine to manage your animations. Art by Elthen: elthen.itch.io/ Text version: godotrecipes.co... Support me on Patreon: / kidscancode
Another great video. In my mind you do the best videos in the field of game development. No other channel has taught me as much as your one. Please never stop sharing these great videos with us. :)
Thank God for this! My animation script was a jumble of awful if statements lol. Thank you for these videos, I know that you dont get a lot of views, but I appreciate every video.
i personally find the if statements easier to keep track of than both having to keep track of if statements, travel commands and the animationtree this made everything more complicated for me, but also seems to be the only way to have the attack animation play till the end before going back to idle
i was checking on the gdquest professional game development course.. and reaching to just this part was so overwhelming.. not saying that the course was bad.. but see this is all it takes to understand how states work.. Great Video!
Great video! I just watched a bunch of other "state machine" videos which just use code (enum). Is this doing exactly the same thing but saving us having to write as muchcode for each state?... when would you use code rather than an animation tree. Pixel Gamemaker relied heavily on this tree approach. I gave up in the end and decide to learn to code :)
Those videos are talking about a generalized state machine for your character, which can handle any aspects of its behavior. This is specifically an *animation* state machine.
It is possible to make a double-attack by checking the current animation state and transition to the second attack only if the first attack's animation is still playing? Moreover, it would be nice to read the current timestamp of the animation. In this case, the physical length of the animation an/or time range during the animation's play would make an excellent condition to perform combo-attacks by hitting the same input action (button) multiple times in the correct time-distances.
i have been using this method: func _physics_process(delta): |> if Input.is_action_pressed("ui_right"): |> |> vel.x = speed |> |> $animation.play("walk") ------------------------------------------------------------------ this is a good way to do it but it has limitation like sliding before going into idle is not possible in this method
Great video to see after hand crafting a complex animation state function that's tightly integrated into all of my scripts... :( lol gonna have a go at tearing down and rebuilding all of my animation code now, see you guys in 5 hours
var current = state_machine.get_current_node() is an invalid call non existent function "get _current_node" in Base NIL also the var current variable is never used so i tried experimenting and removing the line completely, perhaps i dont understand state machines. with out a var current line of code it then seems to bring up a error on state_machine.travel("idle"), right at the end of get input. if i replace this with return the game then loads, but any action or input that requires it to use the .travel function breaks the game and come up with another non existant function "travel" which was the same error the idle arror had. can anyone explain this,
Is there some tutorial where you go over how you setup the animations in the animation player? your animation is in sync with the line, mine just starts when i hit play, and continues even if i pause..
I have the same problem. The walk animation goes back to idle even if I don't tell the code to travel to "idle". This occurs with an enemy I'm trying to implement.
Nice video, it helped me alot :) But I think one detail needs to be added which I found out having troubles with the AnimationNodeStateMachine: Its better to check if the state_machine is playing before you travel to a node, because otherwise you could get an error if the state machine is not active. You do that simply by checking: if state_machine.is_playing(): before you use the travel function. This becomes definetly necessary if you work with sub state machines, as they wont get activated at the beginning.
I know the focus of the video it is the AnimationTree (an Animation State Machine), but would not be perfect to align it with a player state machine, instead of all ifs in process? Something like a node/script and subnodes/subscripts to handle all the logic and attributes of the player in each state. You can par it with the animation state machine and everything would be organized and easy to grow with no big problems.
i love your tutorials , they are short and right to the point , i have a question , im trying to make top down rpg , and i have idleRight,Left,Up,Down , how can i set this up ? :) Thank you for the amazing work
for some reason this didnt work for me, i havent added the attack yet, but just the travel from idle to run and such dosnt work, my character is just stuck in a still frame after adding this. animation player worked fine though, but this seem to be the only way to play a full animation and go back to idle state when button is pressed
So how would you make it so the double attack is not automatic, but instead you can press the attack button twice to first make attack1 and then attack2? like a combo attack
Its also possible to use an AnimatedSprite node and then key in the frames into an animatedPlayer then use the animationTree to control the state machine "AnimatedNodeStateMachineTransitions"? Or does this just only work with Sprite? Sorry if this is a silly question. I'm a beginner in Godot. Why I'm asking is because I already have my SpriteFrames loaded up in one AnimatedSprite and I don't want to start all over again and re-import everything if its not necessary (if AniatedSprite and Sprite are similar enough).
AnimatedSprite can only change textures. In this example we are also moving and enabling/disabling collision shapes. You need AnimationPlayer to do that.
Any possibility you could do another video on this showing how to implement it with 2d platformers? I'm having a lot of trouble getting jumping and falling animations to work smoothly this with animation states
in your code, if the player y velocity is negative (they are going up), then play the jump, if the y velocity is positive (they are falling), play the falling animation
I guess i'm going back to IF statements, because my spritesheet of run jump walk run attack are all on separate spritesheets. Making that work is worse than anything... I cant put 2 sprites on 1 animation player so eventually it's even more clutter. Back to learning GDscript >< My animation only stops walking when i move to the right while holding jump
This doesn't work for me at all. I've followed JayAnAm's tutorial on 3D character movement and it's fine, but I want to add some in between animations for when, say, the character lands on the floor. State Machine can apparently do that, and this is the only well made tutorial for animation state machines, but "var current = state_machine.get_current_node()" throws an error, something about it not existing.
I just encountered this and fixed it. Firstly, check that you didn't capitalize the "parameters/playback" bit. Then make sure you have set a 'start' and 'end' state in the animation player with those two little flag buttons you see next to the trash button. You might run into additional difficulties if you don't have an 'idle' animation (like I don't) but we should be able to figure that part out for ourselves. Hope this advice didn't come too late!
Looking for a video on AnimationTree usage in GDscript, but everyone seems to be covering state machines that can be done easily with a switch case(match)...could you do one that covers accessing animation nodes inside an animation tree...like changing the "add" animation from a one shot...this is one of the things I am fighting with.
I have one strange problem when trying to turn the kinematicbody2d scale: if Input.get_action_strength("ui_right"): input_dir += 1 self.scale.x = 1 if Input.get_action_strength("ui_left"): input_dir -= 1 self.scale.x = -1 But when pressing them it does "blink" and has both left and right looking elements (my animation is build with 1 node with sprite each per element... hand, feet, body, head...) and while "blinking" it does get out of collision with ground and fall down...
Problem solver, avoiding scale, appart from having stuff at the positive range of X axys that when scaled goes auto into negative one which causes clunky animation, it does blink even when fixing it. Finally used a node group to set_flip_h among the whole group and "et voila"
Hello. I'm making fps with godot tutorial. In it animation state tree is not used, states and changin process writed in code. I managed to simplify tutorial code for animation changing to single structure. Guns in tutorial have 5 animations, idle, equip, unequip, fire, reload. In my piece of code i can add weapon with another name but with same 5 animations without changing the code. Is it possible to make such universal structure in animation tree? Because for every new weapon i need to add 5 more animations in to tree. And i want lots of weapons. Animation tree is convenient and have blends, which i want to use too.
hey please help me,I searched in every place and noboady answer me. its works all perfect for me except that when I try to go from "shooting" animation to "idle" at the end, it dosen´t work, "Fire" play very very fast and then "idle" play. Both have the same conditions because my "idle" animation play when velocity is 0 and is_on_floor, and my "Fire" animation too, because I want that you can´t move when you are shooting. I think it is because of when I select in animation tree "at end" it dosen´t work. Shooting on the condition has the key you have to press to shoot, so it enters and change from "idle" to "fire" but then very fast to "idle" again
Hello. I'm in a similar bind. I have the script with animations but either i'm missing a line or have one misplaced. My player moves but only one animation works and doesn't change direction.
How do I detect when the death animation is finished (to reload the scene for example)? With AnimationPlayer I just used the animation_finished signal, but it doesn't work with the state machine, and there's no signal on the AnimationTree.
Please make more vids about mobile game development like: - How to make the character bounce at the edge of the screen - Its all based on random levels - How to make an in game purchase
Aside from in game purchases, none of these things are mobile-related. The official tutorial even shows stopping at screen edges. "Random levels" is way too general - it depends a lot on what type of game you're making. "Level" can mean a lot of different things.
I just don't get way you would ever use something like this. I feel like it all falls apart when you start creating the hurt() and die() functions: you could just as well recall the "hurt" and "die" animations directly from the AnimationPlayer. The only situations I can think of that's easier to handle with the AnimationTree is when you want to concat animations, like when you combo Attack 1 into Attack 2
I believe the animation tree is for handling the transitions between animations (immediate, etc.) and as author mentioned keeps the code cleaner from a bunch of if statements
Good video, but this setup will only work for a very simple character. An involved complicated enemy with AI and the like, I'm still not certain how this will help. Especialyl with areahit boxes and the like. Perhaps I need to think about it more.
Hi I have problem here.i already write code Almost like you,but the Animation/characther still doesn't move.i even have copy your code from internet but still won't move.why this happen?
Hi i followed this tutorial, but changed some things to better suit my game which is a platformer. Whenever I activate the Animation State Machine the Output gets spammed with this scene/animation/animation_tree.cpp:861 - Condition ' !track_cache.has(path) ' is true. Continuing..: and whenever I start the game my error thing gets flooded with this error: E 0:00:02:0964 Condition ' !track_cache.has(path) ' is true. Continuing..: scene/animation/animation_tree.cpp:861 @ _process_graph() Can you please help me understand what is going on and how to fix it. Everything in the game works perfectly fine but I keep on getting this spammed and its killing me.
@@Kidscancode is there a way to check if the animation is finished playing? There's no animation finished signal in the animation tree, and if I use the animation player, it'll return the animation i already set before starting the game
I'm new to Godot and this error keeps happening to me as well. As far as I can tell it is saying "You're asking me to get the position but it's not there." This seemed to be happening whenever I was using the get node function wrong or was calling the property i was trying to grab the wrong name.
Just the first 10 seconds summarize my entire morning
same
Another great video. In my mind you do the best videos in the field of game development. No other channel has taught me as much as your one. Please never stop sharing these great videos with us. :)
This is so much easier than every other tutorial on animations trees out there. Works out of the box. Thanks Chris!
Thank God for this! My animation script was a jumble of awful if statements lol. Thank you for these videos, I know that you dont get a lot of views, but I appreciate every video.
i personally find the if statements easier to keep track of than both having to keep track of if statements, travel commands and the animationtree
this made everything more complicated for me, but also seems to be the only way to have the attack animation play till the end before going back to idle
You're a life saver mate, this is exactly what i was looking for, thank you!
i was checking on the gdquest professional game development course.. and reaching to just this part was so overwhelming.. not saying that the course was bad.. but see this is all it takes to understand how states work.. Great Video!
Wow, godot added statemachine! Niiice!
Thank you KidsCanCode for the tutorial! Amazing job!
Great video and I love the Godot recipes website
Awesome video as always. Thank you for all the effort you put into your content.
These little recipes are really good. Very handy
I didn't even know this was possible, it was very helpful, and I learned a lot thank you.
Great tutorial: really clear and well explained.
Great video! I just watched a bunch of other "state machine" videos which just use code (enum). Is this doing exactly the same thing but saving us having to write as muchcode for each state?... when would you use code rather than an animation tree. Pixel Gamemaker relied heavily on this tree approach. I gave up in the end and decide to learn to code :)
Those videos are talking about a generalized state machine for your character, which can handle any aspects of its behavior. This is specifically an *animation* state machine.
Whoa! This is really powerful...! Thanks for the tutorial.
thanks this is what I was looking for!
It's shown on my TH-cam, this is a great opportunity.
It is possible to make a double-attack by checking the current animation state and transition to the second attack only if the first attack's animation is still playing? Moreover, it would be nice to read the current timestamp of the animation.
In this case, the physical length of the animation an/or time range during the animation's play would make an excellent condition to perform combo-attacks by hitting the same input action (button) multiple times in the correct time-distances.
Thank you so much i was really struggling with the animation tree
"and than there's die, when we reach that state there is no return"
went dark all of a sudden lmao
I have four idle animation {right,left,up,down} and don't know how connect them each other
Some really awesome and useful videos!! thank you
i have been using this method:
func _physics_process(delta):
|> if Input.is_action_pressed("ui_right"):
|> |> vel.x = speed
|> |> $animation.play("walk")
------------------------------------------------------------------
this is a good way to do it but it has limitation like sliding before going into idle is not possible in this method
Great video to see after hand crafting a complex animation state function that's tightly integrated into all of my scripts... :( lol gonna have a go at tearing down and rebuilding all of my animation code now, see you guys in 5 hours
how was the 2 years and 5 hours goes ?
Really nice video.
Absolute unit.
Dude! Thank you! Keep up the awesome videos!
Really interesting. Thank you for posting.
*flashback to unity mecanim*
oh god I dont wanna go back
var current = state_machine.get_current_node() is an invalid call non existent function "get _current_node" in Base NIL
also the var current variable is never used so i tried experimenting and removing the line completely, perhaps i dont understand state machines.
with out a var current line of code it then seems to bring up a error on state_machine.travel("idle"), right at the end of get input. if i replace this with return the game then loads, but any action or input that requires it to use the .travel function breaks the game and come up with another non existant function "travel" which was the same error the idle arror had.
can anyone explain this,
Well.. that solves problems. Soooo many problems. Thanks a lot mate :D
Thank so much bro your a life saver
Love your videos! Keep it up
amazing🌟
For me, the "statemachine.travel("animation_name") is not working.
Any idea what could be wrong? ( I use stable version 3.21 )
state_machine perhaps?
Is there some tutorial where you go over how you setup the animations in the animation player? your animation is in sync with the line, mine just starts when i hit play, and continues even if i pause..
i was missing one word for my code to work, if i had not found this video i may have lost inspiration to continue the creation of my game. Thanks!
Nice video! Love the website aswell.
How do I make the animation playing smooth of the walk, sometimes the animation plays and other times it does not play ? How do I fix it ?
I have the same problem. The walk animation goes back to idle even if I don't tell the code to travel to "idle". This occurs with an enemy I'm trying to implement.
That helped me a lot. Thanks!
thank you for sharing your knowledge! It was greatly helpful to me :)
Nice video, it helped me alot :)
But I think one detail needs to be added which I found out having troubles with the AnimationNodeStateMachine:
Its better to check if the state_machine is playing before you travel to a node, because otherwise you could get an error if the state machine is not active.
You do that simply by checking:
if state_machine.is_playing():
before you use the travel function.
This becomes definetly necessary if you work with sub state machines, as they wont get activated at the beginning.
Yes, I noticed your issue about this.
How did you change the color of the letter of your script
great video man. Thanks for the help!
I know the focus of the video it is the AnimationTree (an Animation State Machine), but would not be perfect to align it with a player state machine, instead of all ifs in process?
Something like a node/script and subnodes/subscripts to handle all the logic and attributes of the player in each state. You can par it with the animation state machine and everything would be organized and easy to grow with no big problems.
Nice work.
Awesome! Thank you!
i love your tutorials , they are short and right to the point , i have a question , im trying to make top down rpg , and i have idleRight,Left,Up,Down , how can i set this up ? :) Thank you for the amazing work
When I use:
$Animationtree.get("parameters/playback").travel("attack1") it won't work, why is that?
is it in func _ready ?
for some reason this didnt work for me, i havent added the attack yet, but just the travel from idle to run and such dosnt work, my character is just stuck in a still frame after adding this.
animation player worked fine though, but this seem to be the only way to play a full animation and go back to idle state when button is pressed
mind blown !!
Thank you very much dude, you really helped me!
So how would you make it so the double attack is not automatic, but instead you can press the attack button twice to first make attack1 and then attack2? like a combo attack
this was very helpful, thanks
Awesome!
does this work for cutout animation? Im using bones and ik and rotating the sprites around
Thank you!
During IDLE it stay stuck at idle left regardless if I've moved right or up before
THAT WAS VERH HELPFUL TNX A LOT ^_^
He sets a var for get_current_node() but never uses it, could anybody tell me what that is for exactly and why it needs to be there?
I have the same question.
Its also possible to use an AnimatedSprite node and then key in the frames into an animatedPlayer then use the animationTree to control the state machine "AnimatedNodeStateMachineTransitions"?
Or does this just only work with Sprite? Sorry if this is a silly question. I'm a beginner in Godot.
Why I'm asking is because I already have my SpriteFrames loaded up in one AnimatedSprite and I don't want to start all over again and re-import everything if its not necessary (if AniatedSprite and Sprite are similar enough).
AnimatedSprite can only change textures. In this example we are also moving and enabling/disabling collision shapes. You need AnimationPlayer to do that.
lovely
Any possibility you could do another video on this showing how to implement it with 2d platformers? I'm having a lot of trouble getting jumping and falling animations to work smoothly this with animation states
in your code, if the player y velocity is negative (they are going up), then play the jump, if the y velocity is positive (they are falling), play the falling animation
awesome, thanks man!
I guess i'm going back to IF statements, because my spritesheet of run jump walk run attack are all on separate spritesheets.
Making that work is worse than anything... I cant put 2 sprites on 1 animation player so eventually it's even more clutter.
Back to learning GDscript >< My animation only stops walking when i move to the right while holding jump
Same problem, I have separate Sprite action, i can't add two action in one spritenode, because are in top or behind between them
> " I cant put 2 sprites on 1 animation player"
Sure you can. AnimationPlayer can control *any* property, including the Sprite's *Texture*.
@@Kidscancode but i need animatedSprite not the normal sprite , still possible?
@@boratsagdiyev1586 yes animated sprite and animation player can be used together
thats very good video
Hi,
How can i reverse the position when my character is attacking in a another way?
$AnimatedSprite.flip_h = true
@@smutnywalen Yeah but that only flips the sprite not the hitbox....
This doesn't work for me at all.
I've followed JayAnAm's tutorial on 3D character movement and it's fine, but I want to add some in between animations for when, say, the character lands on the floor. State Machine can apparently do that, and this is the only well made tutorial for animation state machines, but "var current = state_machine.get_current_node()" throws an error, something about it not existing.
I just encountered this and fixed it. Firstly, check that you didn't capitalize the "parameters/playback" bit. Then make sure you have set a 'start' and 'end' state in the animation player with those two little flag buttons you see next to the trash button. You might run into additional difficulties if you don't have an 'idle' animation (like I don't) but we should be able to figure that part out for ourselves. Hope this advice didn't come too late!
low volume :/
I see start and end but what about an anystate?
How can I add
Jumb and dash
Oh thanks a lot. So many things to screw up.
they must have changed this in 4.0, since i get an error "null"
Looking for a video on AnimationTree usage in GDscript, but everyone seems to be covering state machines that can be done easily with a switch case(match)...could you do one that covers accessing animation nodes inside an animation tree...like changing the "add" animation from a one shot...this is one of the things I am fighting with.
Thanks for the suggestion. I put it on my (unfortunately very long) list! :)
Your videos are so great. I have a newborn child and I can't wait until she get the age of learning how to code. Your channel will be so helpful
I have one strange problem when trying to turn the kinematicbody2d scale:
if Input.get_action_strength("ui_right"):
input_dir += 1
self.scale.x = 1
if Input.get_action_strength("ui_left"):
input_dir -= 1
self.scale.x = -1
But when pressing them it does "blink" and has both left and right looking elements (my animation is build with 1 node with sprite each per element... hand, feet, body, head...) and while "blinking" it does get out of collision with ground and fall down...
Problem solver, avoiding scale, appart from having stuff at the positive range of X axys that when scaled goes auto into negative one which causes clunky animation, it does blink even when fixing it.
Finally used a node group to set_flip_h among the whole group and "et voila"
Hello. I'm making fps with godot tutorial. In it animation state tree is not used, states and changin process writed in code. I managed to simplify tutorial code for animation changing to single structure. Guns in tutorial have 5 animations, idle, equip, unequip, fire, reload. In my piece of code i can add weapon with another name but with same 5 animations without changing the code.
Is it possible to make such universal structure in animation tree? Because for every new weapon i need to add 5 more animations in to tree. And i want lots of weapons.
Animation tree is convenient and have blends, which i want to use too.
is there anyway to stop running and finish the attack animation when you pressed attack while running?
hey please help me,I searched in every place and noboady answer me. its works all perfect for me except that when I try to go from "shooting" animation to "idle" at the end, it dosen´t work, "Fire" play very very fast and then "idle" play. Both have the same conditions because my "idle" animation play when velocity is 0 and is_on_floor, and my "Fire" animation too, because I want that you can´t move when you are shooting. I think it is because of when I select in animation tree "at end" it dosen´t work.
Shooting on the condition has the key you have to press to shoot, so it enters and change from "idle" to "fire" but then very fast to "idle" again
Hello. I'm in a similar bind. I have the script with animations but either i'm missing a line or have one misplaced. My player moves but only one animation works and doesn't change direction.
could u share the project file ? it will be helpful
what does the sync transition do?
wait what ? so i need to use the animation player ..... only spend all day setting this up with the animatedsprite 😢
Hi I am trying to make a platformer and this worked, but the animation speed is too low, so how do I increase the speed?
I cant active animation tree.
1:53
can someone help?
How do I detect when the death animation is finished (to reload the scene for example)? With AnimationPlayer I just used the animation_finished signal, but it doesn't work with the state machine, and there's no signal on the AnimationTree.
Please make more vids about mobile game development like:
- How to make the character bounce at the edge of the screen
- Its all based on random levels
- How to make an in game purchase
Aside from in game purchases, none of these things are mobile-related. The official tutorial even shows stopping at screen edges. "Random levels" is way too general - it depends a lot on what type of game you're making. "Level" can mean a lot of different things.
I just don't get way you would ever use something like this.
I feel like it all falls apart when you start creating the hurt() and die() functions: you could just as well recall the "hurt" and "die" animations directly from the AnimationPlayer.
The only situations I can think of that's easier to handle with the AnimationTree is when you want to concat animations, like when you combo Attack 1 into Attack 2
I believe the animation tree is for handling the transitions between animations (immediate, etc.) and as author mentioned keeps the code cleaner from a bunch of if statements
What is velocity.length? Why not just use velocity.x == 0 or something similar?
Because it's a top down game not a platformer. If there is any movement in a top-down game, then you want to transition to the run state.
What are transition nodes for? It seems you don't use them and some other devs do
Good video, but this setup will only work for a very simple character. An involved complicated enemy with AI and the like, I'm still not certain how this will help. Especialyl with areahit boxes and the like. Perhaps I need to think about it more.
for the two attacks , he does a return, does that mean it returns to idle ?
How do you implement this on godot 4?
Hi
I have problem here.i already write code Almost like you,but the Animation/characther still doesn't move.i even have copy your code from internet but still won't move.why this happen?
Copying the code isn't everything. Did you also add the input events that the code is referencing for movement ("move_left", etc)?
Hi i followed this tutorial, but changed some things to better suit my game which is a platformer. Whenever I activate the Animation State Machine the Output gets spammed with this scene/animation/animation_tree.cpp:861 - Condition ' !track_cache.has(path) ' is true. Continuing..:
and whenever I start the game my error thing gets flooded with this error:
E 0:00:02:0964 Condition ' !track_cache.has(path) ' is true. Continuing..:
scene/animation/animation_tree.cpp:861 @ _process_graph()
Can you please help me understand what is going on and how to fix it. Everything in the game works perfectly fine but I keep on getting this spammed and its killing me.
It seems you have a pair of nodes with no path between them. That's what "!has(path)" would mean.
do you have tips on what to do if i want the attack combo is done by pressing the attack button twice?
You'd need to keep track of when the button is pressed, and if it's pressed again within a certain length of time.
@@Kidscancode is there a way to check if the animation is finished playing? There's no animation finished signal in the animation tree, and if I use the animation player, it'll return the animation i already set before starting the game
But how do you prevent movement during the attacking animation?
You can disable movement during the attack with a flag. Set can_move = false when the animation starts, and then back to true after.
is there a way to blend the animations while also having this state tree?
click on the arrowed line between nodes, and play with the Xfade time, it smoothens it nicely
Edit: removed question and figured it out.
"Attempt to call function 'get_position' in base 'null instance' on a null instance." Why does Godot throw that error message?
I'm new to Godot and this error keeps happening to me as well. As far as I can tell it is saying "You're asking me to get the position but it's not there." This seemed to be happening whenever I was using the get node function wrong or was calling the property i was trying to grab the wrong name.
Same
I hope this is not like Coco2d that was supposed to be the greatest thing to be used with swift and Xamarin.