How To Make a 2D Platformer with AnimationTree in Godot
Вставка
- Опубліковано 20 вер 2020
- This video shows you an advanced but simplified 2D Platformer implementation using the AnimationTree.
Download godot: godotengine.org/download
Code: github.com/NovemberDev/Platfo...
Script: gist.github.com/NovemberDev/1...
Twitter: / november_dev
Most tutorials use the AnimationPlayer and cause beginners to fight with Animation State Transitions as soon as they want to add new functionality. That's where I come in.. - Наука та технологія
That animation callback method as a key was worth this entire tutorial alone. 3 years old tutorial, yet how many Godot users know of that feature? Incredibly useful.
This has actually been the best AnimationTree video I'm personally seen. I feel like most of the ones I've run into stop after 'Wiring Nodes Together' and barely explain 1 tiny line of code. Perhaps I'm an idiot and fail to search correctly, but I've watched over a handful, and only this one gave my proper understanding and function. Thank you! I'll definitely been reccomending you in my next DevLog.
"yes pls click it unlike me" - I'm a total beginner, and this video was both helpful and made me laugh a lot. Thx mate!
Oh my lord this is going to make my life easier. Glad this video popped up in my feed.
The Animated Sprite node is way too underrated. I feel people should use it more often.
Thank you for introducing this option in AnimationTree, I would never have examined it on my own. I will now go and explore the OneShot system for a short "bracing before jump animation"
"But can you do this?" haha
I appreciate these more advanced overview videos for Devs that already have a handle on the basics. :)
Super super useful and concise, thanks!
This tutorial needs more views!!
wow man thanks, I was wondering how do you do an action that usually require on_animation_finished using AnimationTree
I think this adds another layer of indirection which, depending on your project, may actually increase complexity unnecessarily. If you only have 2 or 3 animations, this is going to be overkill. However, when you have a lot more animations and need to figure out how they all interact, this would become very useful. Of course you could still achieve the same in code (what do you think is being generated for you behind the blend tree?), so ultimately it's a matter of preference. I would probably only use the AnimationTree for more complex scenarios. For the example given in the video, I could be swayed either way.
I agree, there aren't any tutorials I know of that show how you can apply an AnimationTree in a 2D setting and it's good to show this as an option. I'd suggest trying everything out and seeing it for yourself, games can be quite different from one to another.
From my experience, as your game grows, this way of separating animationstate from code pays off long term.
You can even go a step further to make use of enums to deal with readability like this:
enum Movement {
Idle = 0,
Walking = 1,
Swimming = 2,
...
}
$AnimationTree.set("parameters/movement/current", Movement.Idle)
@@novemberdev8292 talking about more complicated scenarios (way out of my league but this noob cant help but ask) how does this animation tree perform compared to more direct approaches performance wise?
@@tsk5328
That's hard to say without any testing..
Since the AnimationTree is a whole separate node with it's processing, logically, it will require more power.
But consider the following:
- what can be done with the AnimationTree takes a lot more complex code with the raw AnimationPlayer approach,
which may or may not be less performant if you are inexperienced
- the time it takes you to write and perfect that code is longer than a quick implementation with an AnimationTree,
where you let it figure out the state-transitions - and maybe you can even get away with it
So before you fall into the trap of premature optimization, do whatever is implemented really fast for you.
Then stress test it with 1000 walking enemies (Tree + Player) in the scene (depending on your use-case, like a wave shooter).
If you notice a bottleneck, try the raw approach and see if it helps, if it doesn't, something else is going on...
Never hunt a problem before you haven't verified that the problem even exists - otherwise you search for a ghost in the machine :^)
No work is ever lost, it is always experience that you gain and never shy away from breaking things in the pursuit of finding the simplest and most optimal way
@@novemberdev8292 thanks, that makes a lot of sense, I'm very very much at the very start of the learning curve and mistakes I make now will probably only become apparent to me in time. but this approach definitely simplifies getting into the project, I'm starting with a wave shooter (great guess) as it seems like the simplest way to quickly learn the fundamentals of FPS design.
Thanks!!!
You can call functions from the animation track? How did I miss this feature? I have already seen quite a few Godot animation tutorials.
How do I use animationtree with composite sprites?
ty for this awesome tutorial...
i love it
In order to make this work.. If I wanted to jump I had to set ("parameters/in_air_state/current", 1) In addition to ("parameters/in_air/current", 1)... Any ideas why my in_air_state would not automatically change?
Been looking for a tutorial like this for a while. I stayed with state machines cuz I found them easier, at least until I had like 6 animations interconnected
This is Heaven for me!
Really cool tutorial, nice
thanks so much for this!
This was a good one!
This is so useful!
I also usually just add a little bit to the .y of movement, to "simulate" gravity and eliminate the need for a RayCast2D. But then again, I'm trying to just stick to the in-built Godot KinematicBody2D functionality (as masochistic as that is).
total noob here with 2 silly questions:
1) would this be better optimised for lots of moving/ falling bodies (like a rain of [men] arrows or some other object)?
2) would this intefeer with the animation tree cheaking for idle states and coyote time when one jumps, or will one still have some time to jump after walking off a platform?
Essentially, it creates arrays of nodes.
I need learn more about this. Please!!
Nice video, but I'm newbie and to me it seems to help only to organize the animations to not get confused. In the end you will need code everything anyway... right?
Yea, i thought the same
the code looks cleaner to me, because you don’t have to decide the animation, just set the tree based on values without conditions and let it control animation
is there a way to contact you?
i used this for 3d and works great just needed some small tweeks
That's cool and all but CAN YOU DO THIS? *Looks at two directions at the same time with both eyes*
1:51 jump_forgiveness_time, but what if the time is infinite, which means never forgiven?
The only problem of the animation tree is: sometimes the animation player doesn’t call the method added to the track. :/
You are awesome
I find that when making my own sprites using this, the idle animation stays playing for a moment before the jump animation actually plays. There are delays in the animation switching. Do you know what I could do to fix this?
Hey, that could have two reasons:
1. The line that triggers a switch between grounded and in_air_state is a boolean which indicates that your Raycast2D line is "too long" for the lower bound of your Sprite, so reduce the Raycast2D's cast_to property on the Y axis:
$AnimationTree.set("parameters/in_air_state/current", int(!$RayCast2D.is_colliding()))
2. The x-fade (Crossfade) property on the Transition-Nodes in the AnimationTree is not set to 0, which means there is a delay where godot tries to interpolate the keys in both AnimationPlayer-Tracks with eachother. That only works in 3D or 2D with bones.
If there are any delays between the movement animations, you can lower the 50 in this line here:
$AnimationTree.set("parameters/movement/current", int(direction.length() > 50))
@@novemberdev8292 I'm gonna work on this right away, thanks for the fast reply man! Great video btw, keep it up it helps me so much.
@@novemberdev8292 Yep, changing the set paramter/movement/current,int(direction.length() > 10)) makes my 16x16 game feel really punchy. Amazing, thank you so much! :D
I like dis. Give me more.
Yes the animation player Is very powerfull
I liked your approch
this is a question what does direction do? and if my code doesn't need it what can I use to replace it
direction is the actual movement velocity derived from your direction_input (which means if you go left, right or don't move at all).
Since direction gets interpolated towards the direction_input value, it takes some time to gain enough momentum to move the character towards the direction_input.
So if you stop moving right, you direction_input.x will go from 1 to 0, but your direction.x will slowly go from 1 to 0 in 0.8, 0.7, 0.6 steps over time, so your character doesnt stop abruptly moving to the right.
linear_interpolate is the keyword here, since it takes the target value of 1 (you press right) and the current value (which will be somewhere between 0 and 0.9, depending on if you let go of the right key in the previous frame).
Feel free to ask more questions if I didnt explain it properly
@@novemberdev8292 thanks for the help just one more question if I want an animation to play until the end for something like an attack what would I need to do
@@azuljade1107 That depends on your setup. If you use no AnimationTree, then you have to make sure to make a single AnimationPlayer.play() call and yield for the animation_finished signal.
If you use the AnimationTree, then you can click on a Node and set the XFade-Time in the Inspector (right side) to like 0.25 to give the Animation Transition at least another 0.25s to play the animation youre transitioning from.
For attack animations, I use OneShot-Node, it always plays the Animation until the end and you simply call it with $AnimationTree.set("parameters/my_one_shot_node/active", true) with no further setup required!
@@novemberdev8292 thanks for the help and the quick replies hope you have a good day
Thank you
Please..... make one How To Make a 3D Platformer with AnimationTree in Godot
I literally have the code to move the character, but I just need to create an AnimationTree on the 3D game platform
Where were you when i needed you???
"but can you do this?"
*fucking dies* 💀
I'm just learning programming, godot and I don't have the greatest grasp on things but damn if this wasn't helpful! Thank you.
Did you take down your godot network game video? I loved that one so much
I made it public again - just for you
So very very very VERY VERYYYYYYYYYYYYYYYYY VERYYY good
OH?
oh?
*ooohhhhhhhhhh*
your videos are so high quality that if you ever decide to make a tutorial about a *duelmasters/yugioh/magic/heartstone* kind of game I will finally have to quit with all those excuses and start working.
15:02 cool :v. Btw, I use my school account to give this video 2 likes even throught I think it deserve more. THANKS!
ok for complex animations, but for a 3 state character this is a bit hard work for nothing i think
why dont just use queue( ) from animation player?
Yup , but why?
wow
buuuuut "can you do thiiiis??!" xD
If you have anything complex, the animation tree is kinds cumbersome and useless. You will have a state machine, better yet, a hierarchical state machine and that makes it so easy to play the right animations at the right time plus tons of other benefits. The code has to be structured like this regardless, so, one more line on state_enter functions doesn't make a difference.
Going through all this Blend Tree for 2D platformers is pretty cumbersome imo. and can do more harm than good if you have a ton of different animations.
Well this is for ppl who want to make commercial games with complex systems lol
why you sound like dani lmao
I find the webs and the unnecessary complexity the AnimationTree brings into your project as cumbersome. I think I prefere the coding, actually.
Have you found any limitations to just using animation player and code? I’m thinking the same as you but worried there are somethings ill miss
animationplayer.play(idle)
OR:
animationtree.set("parameters/is_grounded/current", 1)
animationtree.set("parameters/is_running/current", 1)
So, this takes longer to set up, there's more shit going on so it'll perform worse, the code is more verbose and harder to understand, that oneshot node as far as I can tell isn't documented so I have no fucking clue how to set it off...is there an actual reason to bother with this bullshit?
To be honest I agree with you. The code and all is pretty darn hard to understand but on the other hand if your animation and all works smoothly, i can say it was worth all the hard coding.
are you serious right now? if your game consists of like 3 animations then go ahead and use the code, if you need to manage even slightly more complicated animations in your game this is an essential. It has many features.
movement time? bro just call it speed or animation speed
Ayo what was that