Manually created animation state-machine transition is not working

Godot Version

4.5

Question

Hello folks,

I’m not able to make manually created AnimationNodeStateMachineTransition work. The design I have is:

  1. Adding transitions for ALL animations in the AnimationNodeStateMachine;
  2. These transitions have advanced condition which named after the target animation;
  3. I will use my own state machine to set condition depends on state.

Here’s the code how I create transitions for ALL animations:

func _ready() -> void:
	var node_sm = animation_tree.tree_root.get_node("StateMachine")
	if node_sm is AnimationNodeStateMachine:
		var node_list: Array[StringName] = node_sm.get_node_list()
		for i in node_list.size():
			var n1 = node_sm.get_node(node_list[i])
			if n1 is AnimationNodeAnimation:
				for j in node_list.size():
					var n2 = node_sm.get_node(node_list[j])
					if n2 is AnimationNodeAnimation and not i == j and not _has_transition(node_sm, node_list[i], node_list[j]):
						var trans:= AnimationNodeStateMachineTransition.new()
						trans.xfade_time = 0.2
						trans.advance_mode = AnimationNodeStateMachineTransition.ADVANCE_MODE_AUTO
						trans.advance_condition = str(node_list[j])
						node_sm.add_transition(node_list[i], node_list[j], trans)
						#node_sm.set_parameter(str(node_list[j]), false)
						print("Transition added from %s to %s" % [node_list[i], node_list[j]])

The game is running but animation is not playing. I saw following errors in console:

E 0:00:00:894   get_parameter: Condition “!process_state->tree->property_parent_map\[node_state.base_path\].has(p_name)” is true. Returning: Variant()
<C++ Source>  scene/animation/animation_tree.cpp:106 @ get_parameter()

If I uncomment set_parameter(str(node_list[j]), false). Anthor errors occurred before the same errors above indicating set_parameter is failed:

E 0:00:00:879   character.gd:63 @ _ready(): Parameter "process_state" is null.
  <C++ Source>  scene/animation/animation_tree.cpp:76 @ set_parameter()
  <Stack Trace> character.gd:63 @ _ready()

I read the source cpp code (briefly as I’m not a cpp developer) but couldn’t dig out more information.

Does anyone have idea how this should be addressed?

Thanks!

1 Like

You don’t need to call AnimationNode.set_parameter(). This method is only useful when implementing a custom AnimationNode

I don’t see anything wrong in the code you posted. Can you give more info? How are you triggering the advance condition?

I think set_parameter fails because you’re supposed to set it on the animation_tree like this:

$animation_tree.set(“parameters/conditions/your_condition”

But that probably doesn’t have anything to do with the first error..

I triggers condition as follows:

character.animation_tree.set(“parameters/StateMachine/conditions/%s” % param_name, true)

It works fine if I manually added transition in the editor. So my suspicion is either editor does something I missed or the timing to adding transitions in script is not correct.

One thing I noticed in remote: the conditions section appears if I manually create the transition with advance condition ‘sleep‘ in the state machine node:

But in case of adding transition in gdscript. The conditions section is not there.

Okay, after some testing you need to emit AnimationNode.tree_changed in the AnimationNodeStateMachine node manually after adding the transitions.

extends Node


@onready var animation_tree: AnimationTree = $AnimationTree


func _ready() -> void:
	_create_transitions()
	var sm = animation_tree.tree_root as AnimationNodeStateMachine
	sm.tree_changed.emit()
1 Like

Work like a charm. Thank you very much!