I want to animate the movement of a character using AnimationPlayer. The problem is that I will have 2 or more sprite sheets.
I am creating animation frames using keyframes from several Sprite2D. And in order for the frames not to overlap each other, I turn off and turn on the visibility of Sprite2D on the track.
This method seems very clumsy to me. And I would like to know if there is a more elegant way to do this.
My character will have customization of clothes in the future, in order to use AnimatedSprite2D, I will need to draw a sheet of sprites for each individual situation. I also have some items on the layers between the character’s clothes and his head, for example.
I know exactly what you mean!!! I’ve done this by using AnimationTree and nesting state machines into each other, which you can do pretty easily. So the behavior tree (state machine) graph could look like this:
Pretty reasonable. You start in idle, you can run from idle, you can interact from idle. But the blocks aren’t actually animations - they are mini state machines themselves! This is what the interact_SM looks like inside
It’s a super simple wrap of some kind. I just know that the interact should have the Sprite2D_idle active for example. So the use_sprite_idle is just a 0s long animation that hides other Sprite2Ds and makes the right one visible. When you add more sprites, you have to just add their (de)activation to the switch animations.
You could also call a function in these switch animations to figure out which sprites to activate. You mentioned clothes - it’s easy to add a function call to an animation. That function checks which clothes the player has equipped and activates the appropriate nodes. Could work.
Now that I’m thinking about it, you could do the same by calling a function in your animation. That way you don’t have to nest state machines, which feels a little complicated…
Godot doesn’t let you pass a Node into the function via the animation player, but I guess NodePath is close enough. It gives you the nice picker when binding arguments to the function call