So I am trying to create a 2D top down game, I have the animations in a AnimationPlayer and I want to use a AnimationTree to control. I did get it to work but I don't understand why it works:
Here is the code:
extends CharacterBody2D
@onready var direction : Vector2 = Vector2.ZERO
@onready var animation_tree = $AnimationTree
@onready var state_machine = animation_tree.get("parameters/playback")
@export var speed : float = 100
@export var starting_direction : Vector2 = Vector2(0,0.1)
func _ready():
animation_tree.set('parameters/Idle/blend_position', starting_direction)
func _physics_process(_delta):
direction = Input.get_vector("left", "right", "up", "down")
velocity = direction * speed
pick_new_state()
update_animation()
move_and_slide()
print(state_machine.get_current_node())
func update_animation():
if direction != Vector2.ZERO:
animation_tree.set("parameters/Walk/blend_position", direction)
animation_tree.set("parameters/Idle/blend_position", direction)
animation_tree.set("parameters/Shoot/blend_position", direction)
func pick_new_state():
if state_machine.get_current_node() != 'Shoot':
if velocity != Vector2.ZERO and state_machine.get_current_node() != 'Walk':
state_machine.travel('Walk')
if velocity == Vector2.ZERO and state_machine.get_current_node() != 'Idle':
state_machine.travel('Idle')
if Input.is_action_just_pressed("shoot"):
state_machine.travel('Shoot')
and the statemachine looks like this:

In terms of what I don't get:
- For the node connections, what is the difference between Enabled and Disabled? I know this seems like a silly question but in the code I can use state_machine.travel to move to another node even if the connection is disabled. However, if I disable the connection between Idle and Walk in my example I get weird results.
- In fact, state_machine.travel can travel to states that are not connected in the AnimationTree at all, I am really confused by that one.
- When I am picking a new state, so the pick_new_state function, I encountered the problem that setting a new state resets the animation. For that I added the additional check state_machine.get_current_node() != 'Walk' which works but feels clunky. Is there a better way of doing this?
I know it's a lot, thank you so much in advance for whoever is willing to help 🙂