Calling "anim_state.travel("Attack")" does seem to actually travel to the node.

Godot Version

v4.4.1.stable.official

Question

I have set up an animation tree to control a player’s movements and attack animations. When using the travel call on my tree, it works for my idle, run, and turn animations, but not for any of my attack animations.

I have my tree structured as an Idle, Run, Attack, and Turn blend tree nodes with all of the appropriate connections. In the blend tree node there are blend spaces that determine the direction of the animations.

My attack animations seem to work, when I manually run them from the tree, just not in code. I have the same problem with my turn animation, but then I deleted the node and remade it and it seemingly went away. I have done this multiple times with my attack node but it never works.

Here is my code for reference:

extends CharacterBody2D

const MAX_SPEED = 100.0
const ACCELERATION = 600.0
const DECELERATION = 800.0

@onready var anim_tree = $AnimationTree
@onready var anim_state = anim_tree.get(“parameters/playback”)

var last_horizontal_direction := 1.0 # 1 = right, -1 = left
var current_horizontal_direction := 1.0
var isAttacking = false

func _physics_process(delta: float) → void:
if isAttacking:
return # Skip movement during attack

handle_attack_input()

var input_vector = Vector2.ZERO
input_vector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
input_vector.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
input_vector = input_vector.normalized()

if input_vector.x != 0:
	current_horizontal_direction = sign(input_vector.x)

# Move logic
if input_vector != Vector2.ZERO:
	var target_velocity = input_vector * MAX_SPEED
	velocity = velocity.move_toward(target_velocity, ACCELERATION * delta)

	# Trigger turn if changing direction
	if current_horizontal_direction != last_horizontal_direction:
		anim_state.travel("Turn")
		anim_tree.set("parameters/Turn/BlendSpace1D/blend_position", current_horizontal_direction)
	else:
		anim_state.travel("Run")
		anim_tree.set("parameters/Run/BlendSpace1D/blend_position", current_horizontal_direction)
else:
	velocity = velocity.move_toward(Vector2.ZERO, DECELERATION * delta)
	anim_state.travel("Idle")
	anim_tree.set("parameters/Idle/BlendSpace1D/blend_position", last_horizontal_direction)

# Update direction after movement logic
if input_vector.x != 0:
	last_horizontal_direction = current_horizontal_direction

move_and_slide()

func handle_attack_input() → void:
var attack_type = null

if Input.is_action_just_pressed("attack_front"):
	attack_type = 0
elif Input.is_action_just_pressed("attack_left"):
	attack_type = -1
elif Input.is_action_just_pressed("attack_right"):
	attack_type = 1

if attack_type != null:
	isAttacking = true
	anim_state.travel("Attack")
	anim_tree.set("parameters/Attack/BlendSpace2D/blend_position", Vector2(last_horizontal_direction, attack_type))

func _on_animation_tree_animation_finished(anim_name: StringName) → void:
if “Attack” in anim_name:
isAttacking = false

You are always traveling back to another state in the movement logic. You should move the if isAttacking: return block to after calling handle_attack_input()

Thanks! Worked immediately lol.