Wait until Animation is finished?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Skayo
:warning: Old Version Published before Godot 3 was released.

I have a script wich plays multible animations after each other, but if I execute it, it plays every animation at once. (Note that the animation sequence is changing everytime it executes)
How can i wait until the animation is finished and then call the next animation?


Thanks for help,
Skayo

:bust_in_silhouette: Reply From: bruteforce

Connect the AnimationPlayer’s “finished” signal to a function, that starts the next animation!
For example:

onready var player = get_node("AnimationPlayer")

func _ready():
	player.connect("finished", self, "playNextAnim")
	player.play("anim_1");

func playNextAnim():
	if(player.get_current_animation() == "anim_1"):
		player.play("anim_2")

Brilliantly simple. Nice

Robster | 2017-02-05 22:32

In Godot 3.3 , the callback is “animation_finished”, and passes in a parameter ‘anim_name’… i had to pass that into the playNextAnim above, as my ‘player.get_current_animation() would return an empty string on finished’

cs341 | 2021-08-25 05:21

:bust_in_silhouette: Reply From: Gokudomatic2

Somewhere In the official docs, there’s your answer in the yield function:

yield( get_node("AnimationPlayer"), "finished" )

For your example, it’ll look like :

onready var player = get_node("AnimationPlayer")

func do_my_animation_sequence:
    player.play("anim_1")
    yield( player, "finished" )
    player.play("anim_2")
    yield( player, "finished" )
    player.play("anim_3")
    ...

I found that the line below cannot work now:

yield(get_node("AnimationPlayer"), "finished")

But this code works:

yield(get_node("AnimationPlayer"), "animation_finished")

I test in Godot 3.0.6.

SpkingR | 2018-11-15 14:45

That is because in Godot 3, the “finished” signal has been changed to “animation_finished”.
So “finished” should work for Godot 2 and “animation_finished” for Godot 3

xiaolongliukang | 2019-12-24 16:53

Cool, now have a hitting animation! Thanks!

Wodsobe Dobe | 2020-02-17 03:47

Best answer IMHO, use animation_finished for godot 3.0 upwards

luiscesjr | 2022-03-20 22:14

:bust_in_silhouette: Reply From: luislodosm

You can create a function to lock the animation and call it from the animation track.

var animation_is_active = false

func _process(delta):
    if Input.is_action_just_pressed("ui_attack") and not animation_is_active: 
        animation_player("attack")

# Method called in first key (true) and last key (false) of the animation track
func activate_animation(state): 
    animation_is_active = state

It’s better to use animation_finished() signal.

luislodosm | 2022-02-24 12:12

You are right, but sometimes we only need to get that in one situation, the signal is better, but if you want to play the same animation multiple times, and after each do something different, the yield(get_node("AnimationPlayer"), "animation_finished") is better

JoluMorsanDev | 2022-03-17 00:33

:bust_in_silhouette: Reply From: idbrii

In Godot 4, the syntax for waiting for the animation_finished event is different. Awaiting for signals or coroutines explains await, but in summary it’s like this:

await $AnimationPlayer.animation_finished

Converting Gokudomatic2’s excellent Godot 2/3 answer looks like this:

@onready var player = $AnimationPlayer

func do_my_animation_sequence():
	player.play("anim_1")
	await player.animation_finished
	player.play("anim_2")
	await player.animation_finished
	player.play("anim_3")
	...

I used something like $AnimationPlayer.animation_finished but I’m getting these errors:

emit_signalp: Error calling from signal 'animation_finished' to callable: 'CharacterBody2D(basic_enemy.gd)::_on_animation_player_animation_finished': Method not found.

Any clue what I can do to resolve this? Thanks.

RendCycle | 2023-06-28 13:01

I think I got it. I used the built-in “animation_finished” Node connect of the AnimationPlayer which automatically added the function and then I edited the related code that calls it to this:

func _process(delta):
		
	if is_dead == true:
		animation_player.play("death")
		_on_animation_player_animation_finished("death")

func _on_animation_player_animation_finished(anim_name):
	await animation_player.animation_finished
	queue_free()

The error messages disappeared. :slight_smile:

RendCycle | 2023-06-28 13:29

@rendcycle: You should be able to collapse that code down to this:

var animation_player = $WhateverYouCalledTheNode
func _process(delta):
	if is_dead:
		animation_player.play("death")
		await animation_player.animation_finished
		queue_free()

idbrii | 2023-07-01 14:50

You’re right. I’m new to Godot and still figuring things out so I thought I still needed to have the “animation_finished” Signals Node of the AnimationPlayer connected to make “await” work. Thanks for showing me a clear and clean solution! :slight_smile:

RendCycle | 2023-07-01 15:52