Animation Swap Error

Godot Version

v4.2.1 stable (.net version)

Question

I recently started programming with GDScript, and I’m working on a part of the code, where I have the animation for attacking while moving that works normally, but the animation for attacking while stationary doesn’t work, can anyone help me?

Code snippet

    if (_is_attacking):
        if (_idle == "idle"):
            sprite_2d.animation = "attack"
        elif (_idle == "idle_up"):
            sprite_2d.animation = "attack_up"
        elif (_idle == "idle_down"):
            sprite_2d.animation = "attack_down"

Full code

extends CharacterBody2D

# Declaration of variables exported to the editor
@export_category("Variables")
@onready var sprite_2d = $Texture
@export var _move_speed: float = 64.0
@export var _acceleration: float = 0.2
@export var _friction: float = 0.2
@export var _attack_timer: Timer = null

# Local variables
var _idle: String = "idle_down"
var _is_attacking: bool = false

func _physics_process(_delta: float) -> void:
    _move()  # Call the movement function
    _attack()  # Call the attack function
    move_and_slide()  # Godot's integrated function for physical movement

func _move() -> void:
    var _direction: Vector2 = Vector2(
        Input.get_axis("move_left", "move_right"),
        Input.get_axis("move_up", "move_down")
    )
    
    if _direction != Vector2.ZERO:    
        _animate(_direction)  # Calls the animation function based on the movement direction
        return

    sprite_2d.animation = _idle  # Sets animation to idle when there is no movement
    
    # Movement and friction logic
    velocity.x = lerp(velocity.x, _direction.normalized().x * _move_speed, _friction)
    velocity.y = lerp(velocity.y, _direction.normalized().y * _move_speed, _friction)

func _attack() -> void:
    if Input.is_action_just_pressed("attack") and not _is_attacking:
        _attack_timer.start()  # Starts the timer to control the attack
        _is_attacking = true  # Sets the attack flag as true

func _animate(_direction: Vector2) -> void:
    # Logic to determine animation based on movement direction and attack state
    if abs(velocity.x) > abs(velocity.y):
        sprite_2d.flip_h = velocity.x < 0
        _idle = "idle"
        
        if (_is_attacking):
            sprite_2d.animation = "attack"
        else:
            sprite_2d.animation = "walk"
            
    else:
        if velocity.y < 0:
            _idle = "idle_up"
            
            if (_is_attacking):
                sprite_2d.animation = "attack_up"
            else:
                sprite_2d.animation = "walk_up"
        else:
            _idle = "idle_down"
            
            if (_is_attacking):
                sprite_2d.animation = "attack_down"
            else:
                sprite_2d.animation = "walk_down"
            
    # Additional logic to handle attack animations when standing still
    #===========================================================================
    if (_is_attacking):
        if (_idle == "idle"):
            sprite_2d.animation = "attack"
        elif (_idle == "idle_up"):
            sprite_2d.animation = "attack_up"
        elif (_idle == "idle_down"):
            sprite_2d.animation = "attack_down"
    #===========================================================================
    
    # Movement and friction logic
    velocity.x = lerp(velocity.x, _direction.normalized().x * _move_speed, _acceleration)
    velocity.y = lerp(velocity.y, _direction.normalized().y * _move_speed, _acceleration)
    
func _on_attack_timer_timeout() -> void:
    _is_attacking = false  # Resets the attack state after the timer's time limit

I don’t see an apparent logic error and also no error alert in the console

When you stop moving isn’t _direction equal to Vector2.ZERO, thus not entering your _animate function call?

1 Like

Thank you, I corrected the code and now I can attack without moving.

# rest of the code

	if _direction != Vector2.ZERO:    
		_animate(_direction)  # Calls the animation function based on the movement direction
		return

	sprite_2d.animation = _idle  # Sets animation to idle when there is no movement
	# Additional logic to handle attack animations when standing still

	if (_is_attacking):
		if (_idle == "idle"):
			sprite_2d.animation = "attack"
		elif (_idle == "idle_up"):
			sprite_2d.animation = "attack_up"
		elif (_idle == "idle_down"):
			sprite_2d.animation = "attack_down"

# rest of the code

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.