derkork / godot-statecharts

A state charts extension for Godot 4
MIT License
761 stars 39 forks source link

How to structure nested animation tree states? #27

Closed Shadowblitz16 closed 1 year ago

Shadowblitz16 commented 1 year ago

Should animation tree states derive from compound state?

image

derkork commented 1 year ago

When you see a duplication of the same state names like this, it is a strong indicator that these states are independent of each other. In your example you have vertical motion states (rising, falling ,landing, grounded) and you have states indicating whether the player is currently shooting (passive, shooting). They are independent in that you can change your vertical motion no matter whether you are currently firing, and you can fire no matter what your current vertical motion state is.

Whenever you have independent states, its a good idea to use a parallel node, otherwise your tree will explode with state combinations. This is where state charts have an advantage over plain finite state machines.

I also tend to use a separate parallel tree section for animation control, which runs independently from the rest of the tree because more often than not animation control can be a lot simpler than the rest. You can see this in the platformer example for the ninja frog:

image

So in your specific case (without knowing how exactly the animation tree is set up), I'd probably go with something like this for animation control:

image

The AnimationTreeState node may not be super helpful in this scenario, because you will probably need some nested state machines in your animation tree to handle state combinations (e.g. firing while grounded will likely look different from firing while airborne). The AnimationTreeState node is very simple, it just travels to a state in the root state machine of the animation tree. If you need more control, you can also model this with normal atomic states and then call the appropriate functions on your animation when the state is entered (e.g. use the "state_entered" signal, bind it to your own function and call your animation tree). This way you still get the benefits of using a state machine.

That being said, I'm by no means an expert on the animation tree and particularly not on 3D animation, so there may be more efficient ways to do it.

Shadowblitz16 commented 1 year ago

@derkork how do I set up my animation tree to work with this? Do I have to set up the same transitions in my animation tree I set up in my state chart? How do I stop the animation tree from flip flopping back and forth between animations? How do I wait for animations to end?

Shadowblitz16 commented 12 months ago

@derkork you there? animation tree doesn't support parallel states

derkork commented 12 months ago

@derkork how do I set up my animation tree to work with this? Do I have to set up the same transitions in my animation tree I set up in my state chart? How do I stop the animation tree from flip flopping back and forth between animations? How do I wait for animations to end?

That very much depends on what animations you have and how you want to trigger them. Also you will probably also have to communicate with your animation tree in your scripts as well to set blending values (e.g. using a blendspace to blend between idle/walking/running).

In the platformer demo I had only two states governing the animation of the frog in the state chart(Idle and Moving) . The blending between walking, jumping and falling was done by setting blend space values which the animation state machine used to blend between the various animations:

image

So in general the states of the state chart and the animation state machine may have not much overlap, as some parts that are states in the state chart are blend spaces in the animation tree. For more complex animation I wouldn't even use the AnimationTreeState/AnimationPlayerState nodes. They are really only a helper to quickly set up simple scenarios (that's why they are also marked as experimental in the documentation and I am seriously considering to remove them again as they seem to be a constant source of confusion).

In the end it's a combination of blends and state travels. As I said before, I am not an expert on animation and especially not 3D animation so I cannot give you any useful advice beyond that.

Shadowblitz16 commented 12 months ago

@derkork what do I set animation tree transitions to? immediate, at sync or at end? I want them to only travel to the animation tree state if the state chart state is active. image

derkork commented 12 months ago

I think this could be easier if you used a blendspace to model rising/falling rather than states. Then again, I'm no expert on how to structure animations, so it might be more fruitful to ask questions like this elsewhere, e.g. in the Godot Forums or the Godot Discord