Godot Version
4.2.2
Question
I have an AnimationTree with a script attached to it. Within the script I have the following two signal handling functions:
func _on_animation_started(anim_name: StringName) → void:
print("Animation started ", anim_name)
func _on_animation_finished(anim_name: StringName) → void:
print("Animation finished ", anim_name)
They have the green arrow next to them for being properly hooked up. I am playing a lot of non-looping animations through this animation tree, but the two signals never get fired. Am I doing something wrong, or could this be a bug?
UPDATE: One of my animations randomly fires both signals. But I have around 10 animations, and all the other ones fire nothing.
These signals don’t fire for looping animations. I had a lot of problems with it too but I found a solution.
There is a signal for when the animation is applied so you can implement the firing yourself when it happens. Then you can use animation_started/animation_finished
as usual.
extends AnimationTree
## Path to the AnimationNodeStateMachine.
## Leave empty if the root of the AnimationTree is the state machine.
@export var state_machine = "MainState"
var _state_machine:AnimationNodeStateMachine
var _playback:AnimationNodeStateMachinePlayback
var _previous_anim_node = ""
func _ready() -> void:
_state_machine = tree_root.get_node(state_machine)
_playback = get("parameters/%s/playback" % state_machine)
_previous_anim_node = _playback.get_current_node()
mixer_applied.connect(_on_mixer_applied)
## Implements emmiting finished and started signals for looping states
func _on_mixer_applied():
var node_name = _playback.get_current_node()
var node = _state_machine.get_node(node_name) as AnimationNodeAnimation
var animation = get_animation(node.animation) if _state_machine else null
if animation.loop_mode == Animation.LOOP_LINEAR:
if _previous_anim_node != node_name:
animation_finished.emit(_previous_anim_node)
animation_started.emit(node_name)
_previous_anim_node = node_name