Quick answer: An AnimationTree with active = false never advances any state. Set tree.active = true in _ready, point anim_player at the right AnimationPlayer, and call playback.travel("Run") with the exact state name. If transitions still ignore your call, verify the AnimationPlayer actually contains the named animation.
Here is how to fix Godot AnimationTree state machines that refuse to leave the initial state. You wire up your states in the editor, write playback.travel("Run"), and the character keeps idling. No errors. No warnings. The Animation panel shows the initial state highlighted, but nothing moves it. The AnimationTree has a few requirements that the editor does not enforce, and missing any one is silent.
The Symptom
Your AnimationTree is set up with a StateMachine root containing Idle, Run, Jump, and Land states. The character spawns in Idle and stays there. travel calls return without error. The Inspector shows parameters/playback listed but its value is unchanging.
What Causes This
AnimationTree.active is false. The default value is false. Without setting it true, no state machine inside the tree advances at all.
anim_player path is wrong. The AnimationTree references an AnimationPlayer via the anim_player NodePath. If that path resolves to nothing, animations cannot play but transitions also cannot fire because their durations depend on animation lengths.
Calling travel on the wrong path. The playback object must be retrieved via tree.get("parameters/playback"). Calling travel on the AnimationTree node directly does nothing.
State name mismatch. Travel calls are case-sensitive. travel("run") when the state is named “Run” silently fails.
Missing animation. If the state references an animation that no longer exists in the AnimationPlayer (renamed, deleted), the transition aborts and you stay in the previous state.
The Fix
Step 1: Activate the tree.
extends CharacterBody2D
@onready var tree: AnimationTree = $AnimationTree
@onready var playback: AnimationNodeStateMachinePlayback = tree.get("parameters/playback")
func _ready():
tree.active = true
playback.travel("Idle")
Step 2: Drive transitions from input.
func _physics_process(delta: float):
var input_x = Input.get_axis("move_left", "move_right")
if abs(input_x) > 0.1:
playback.travel("Run")
else:
playback.travel("Idle")
velocity.x = input_x * 200.0
move_and_slide()
Step 3: Verify the anim_player path. Click the AnimationTree node in the Scene tree. In the Inspector, the Anim Player property must show a valid path like ../AnimationPlayer. If empty or red-highlighted, browse and reassign.
Step 4: Check state names match exactly. Open the StateMachine in the AnimationTree editor. Hover over each state to confirm its label. Use the same casing in your travel calls. Use string constants if you are worried about typos:
const STATE_IDLE := "Idle"
const STATE_RUN := "Run"
const STATE_JUMP := "Jump"
playback.travel(STATE_RUN)
Step 5: Use advance conditions for declarative transitions. Open a transition arrow, set Advance Mode to Auto, and write a condition like is_running. Then set the parameter from script:
tree.set("parameters/conditions/is_running", abs(input_x) > 0.1)
Auto transitions fire whenever the condition flips true, without needing explicit travel calls.
Debugging With Print Statements
Log the current state every physics frame:
func _process(delta: float):
print("State: ", playback.get_current_node())
If the printed state never changes despite travel calls, the tree is inactive or the playback handle is stale. If the state changes but the visible animation does not, the issue is on the AnimationPlayer side — missing animations or wrong tracks.
“active = true. anim_player is valid. State names match exactly. Travel a real state. The four checks that wake a state machine.”
Related Issues
For other animation problems, see Godot PhysicsMaterial Bounce. For autoloads not seen by tree, see Autoload Not Accessible.
tree.active = true. The single line that changes everything.