AnimationTree animation_started/animation_finished not firing?

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