0 votes

I'm trying to make a class AnimationChain that will play a list of Animations in an AnimationPlayer back to back. This part is working fine. However, I also want it to detect if another animation is played on the AnimationPlayer that interrupts the AnimationChain.

i.e. I start a chain of animations like ["idledown", "idleright", "idleleft"] with the AnimationChain and then somewhere else in code I call AnimationPlayer.play("idleup") while the AnimationChain is still running.

The problem is that I tried to connect the "animation_changed" signal to a function on the AnimationChain class and it is never fired. I tried the same with "animation_started"and it fires as usual.

Here is the code for AnimationChain:

extends Node

class_name AnimationChain

signal finished

var animation_player: AnimationPlayer
var is_interrupted = false
var is_playing = false

func _init(ap: AnimationPlayer):
    animation_player = ap

    var err = animation_player.connect("animation_changed", self, "interrupted")
        if err:
            print("Error initializing AnimationChain")

    err = animation_player.connect("animation_started", self, "started")
    if err:
    print("Error initializing AnimationChain")

func started(_new_name: String):
    print("Started")

func interrupted(old_name: String, new_name: String):
    print("Interrupted ", old_name, "with ", new_name)
    is_interrupted = true

func run(animations: PoolStringArray, _durations = null):
    is_playing = true
    is_interrupted = false
    if animation_player.current_animation == animations[0]:
        animation_player.seek(0, true)

    for i in range(animations.size()):
        var animation_name = animations[i]

        animation_player.play(animation_name)

        yield(animation_player, "animation_finished")

        if is_interrupted:
            print("Animation chain interrupted, not finishing!")
            is_playing = false
            emit_signal("finished")
                return

        is_playing = false
        emit_signal("finished")

And I start the AnimationChain with:

 bb.animation_chain.run(["idle_down", "idle_down_right", "idle_down_left"])

then interrupt it a few frames later with

animation_player.play("idle_up")

This animates exactly as I expect it to. The started function is called at the beginning of each animation in the chain and when I interrupt with the "idleup" animation, but the interrupt/animation_changed function never is called.

Maybe I'm mistaken when the animation_changed signal is called? Thanks for any suggestions/help!

in Engine by (24 points)

1 Answer

0 votes
Best answer

Never mind, I misunderstood when animation_changed would fire.

This link: https://github.com/godotengine/godot/issues/3520 mentions the animation_changed signal is only "meant to be called when a queued animation starts". Given I'm not queuing animations this doesn't apply to me

by (24 points)
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 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.