Search code examples
animation2dgodotgdscriptgodot4

Blendspace 2D not updating when input direction is changed


I'm trying to animate a 2D character using a blendspace2D in an animation tree. I've built a basic state machine where, when the charge input is detected while the directional movement is not (0, 0), the state changes to the DASH state and remains there until the charge button is released, with the animation state changing to the Dash animation blendspace2D. However, while in the DASH state, the animation doesn't update if I change directions, e.g., if I dash left and then move right while dashing, the animation doesn't change so the character goes backwards. While not in the DASH state, I have a similar blendspace2D for normal movement, which updates the animations correctly. My code to manage the player character, including the state machine and blendspaces is below.

extends CharacterBody2D
class_name Player

@export var ACCELERATION = 17
@export var MAX_SPEED = 100
@export var FRICTION = 100
@export var DASH_SPEED = MAX_SPEED * 1.5
var direction = Vector2.ZERO
enum{
    MOVE,
    DASH,
    CHARGE,
    ATTACK
}
var state = MOVE


@onready var animation_player = $AnimationPlayer
@onready var animation_tree = $AnimationTree
@onready var animation_state = animation_tree.get("parameters/playback")
@onready var sprite_2d = $Sprite2D
#@onready var animation_state = animation_tree.get("parameters/playback")
#var direction_changed = false

var anim_dir = Vector2.ZERO 
 
func _ready():
    animation_tree.active = true

func _process(_delta):
    direction = Vector2.ZERO

    anim_dir.x = Input.get_axis("move_left", "move_right")
    
    anim_dir.y = Input.get_axis("move_up", "move_down")
    direction = anim_dir.normalized()
    

func _physics_process(delta):

    match state:
        MOVE:
            move_state(delta)
        DASH:
            dash_state(delta)
        CHARGE: 
            charge_state(delta)
        ATTACK:
            attack_state(delta)
            
func move_state(delta):

    if direction.length()!= 0:

        if anim_dir.x !=0:
            set_animation_parameters()

        velocity = velocity.move_toward(direction * MAX_SPEED, ACCELERATION)
        move_and_slide()
        animation_state.travel("Move")
        if Input.is_action_just_pressed("charge"):
            state = DASH
        
    else:
        velocity = velocity.move_toward(Vector2.ZERO, FRICTION) 
        if Input.is_action_just_pressed("charge"):
            state = CHARGE
    
        
        animation_state.travel("Idle")

    

func set_animation_parameters():
    animation_tree.set("parameters/Idle/blend_position", anim_dir)
    animation_tree.set("parameters/Move/blend_position", anim_dir)
    animation_tree.set("parameters/Dash/blend_position", anim_dir)
    
func dash_state(delta):
    if direction.length()>0:
        if anim_dir.x != 0:
            set_animation_parameters()
        velocity = velocity.move_toward(direction * DASH_SPEED, ACCELERATION)
        move_and_slide()
        animation_state.travel("Dash")
    if Input.is_action_just_released("charge"):
        state=MOVE
        
func attack_state(delta):
    pass
func charge_state(delta):
    print("charging...")
    
    if Input.is_action_just_released("charge"):
        state = MOVE

As you can see, I set the animation parameters for each state while both moving and dashing and have the animation_state travel to Dash and Move in the same way, yet the latter works and the former doesn't. As far as I can tell it's not because the Move animation state gets interrupted by the Idle animation state, as I can change directions by holding the input vertically without resetting to the Idle animation and it still works.

Here's my animation tree setup: animation tree for player character

Here's the Move state's blendspace2D where every point on the left is the left moving animation and every point on the right is the right moving animation enter image description here

And here's the Dash state with the same setup as the Move state

enter image description here

I've tried everything I can think of and have come up empty. Any help would be appreciated.


Solution

  • Solution: Blend parameter was set incorrectly to be continuous in the Dash state. I set it to be discrete, just as in the Move state's Blend parameter and it worked.