0 votes

example

In the example above I have two custom animations, A and C. They both start and end at completely different positions.

At the end of animation A, I want Godot to automatically generate a new animation, B, that transitions to the first frame of C. Importantly, I need to be able to trigger that new animation at any point during the lifecycle of animation A, whether it just started, is halfway through, or is at the end. Ideally there would be a crossfade between A and B as B becomes active.

I've spent a good couple of hours crawling through the docs and messing around with AnimationTree and I'm getting nowhere. Does anyone know if there's a way to do this natively in Godot?

in Engine by (12 points)

1 Answer

0 votes

In the animation editor in the AnimationPlayer, click Animation -> Edit Transitions to set cross-animation blending. You can overwrite the blending when calling AnimationPlayer.play() too.
The value is how much time the animation will take to have 100% effect. If A is playing, then C starts and its blend time is 0.5; it will take half a second to completely switch to C.

func go_from_A_to_C() -> void:
    $AnimationPlayer.play("A")

    #Start C after 300 milliseconds
    var timer = get_tree().create_timer(0.3)
    yield(timer, "timeout")
    $AnimationPlayer.play("C", 0.5)
by (148 points)

I might be misunderstanding you, but isn't this just going to blend the two animations? Ie. animation C will start immediately before animation A has finished, and the blend will just some mixture of the two.

My use case is that A finishes at some point in its lifecycle, animation B begins and finishes, and then finally animation C starts. Optionally, there would be some blending between A and B, and B and C.

The more I look into this more I'm starting to conclude that Godot just can't do this, and I'm going to need to programmatically create and inject the intermediary animations using the Tween node.

You misunderstand the purpose of the code. play(C) doesn't execute soon after play(A). The yield(timer, "timeout") line freezes the function's execution and waits for a timer of 0.3 seconds to finish to resume execution. Because of it, $AnimationPlayer.play("C", 0.5) is executed 0.3 seconds after $AnimationPlayer.play("A").

Take a look at Coroutines with yield. Particularly, Coroutines & signals. It's my favorite GDScript feature because it simplifies a lot the coding of a sequence of actions that don't happen at the same time.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.