Godot Version
Godot 4.2.2
Question
I have a simple 2D sprite character that moves in 4 directions: up, down, left and right. The character has attack animations for these 4 directions, and idle animations for these directions as well.
The character moves in all directions displaying the correct animations, and attack in all directions displaying all correct animations.
Problem:
The idle animation is not playing properly. It’s defaulting to the last idle animation, and not displaying the correct idle animation based on direction.
I am still new to coding but i tried different new concepts in one go, and I am sure i missed something somewhere. I appreciate your guidance.
extends CharacterBody2D
var speed = 100
var playerState = "idle"
var is_attacking = false
var dir = Vector2.ZERO
func _physics_process(delta):
# Get player's input for movement, W A S D
var direction = Input.get_vector("left", "right", "up", "down")
# Update player state based on direction
update_player_state(direction)
if Input.is_action_just_pressed("attack") and not is_attacking:
attacking()
if not is_attacking:
handle_movement(direction)
play_anim()
else:
play_anim() # Ensure attack animation plays if attacking
func update_player_state(direction: Vector2):
if direction.x == 0 and direction.y == 0:
playerState = "idle"
else:
playerState = "walking"
# Update direction for animation purposes / dir is not updated??
dir = direction
print(dir)
func handle_movement(direction: Vector2):
velocity = direction * speed
move_and_slide()
func play_anim():
if is_attacking:
play_attack_anim()
elif playerState == "idle":
play_idle_anim()
elif playerState == "walking":
play_walk_anim()
func play_idle_anim():
match dir:
Vector2.UP:
$AnimatedSprite2D.play("up_idle")
Vector2.RIGHT:
$AnimatedSprite2D.play("right_idle")
Vector2.DOWN:
$AnimatedSprite2D.play("down_idle")
Vector2.LEFT:
$AnimatedSprite2D.play("left_idle")
_:
$AnimatedSprite2D.play("down_idle")
#default, if others not call for some reason
#it's always using this last one..
func play_attack_anim():
match dir:
Vector2.UP:
$AnimatedSprite2D.play("up_attack")
Vector2.RIGHT:
$AnimatedSprite2D.play("right_attack")
Vector2.DOWN:
$AnimatedSprite2D.play("down_attack")
Vector2.LEFT:
$AnimatedSprite2D.play("left_attack")
func play_walk_anim():
match dir:
Vector2.UP:
$AnimatedSprite2D.play("up_walk")
Vector2.RIGHT:
$AnimatedSprite2D.play("right_walk")
Vector2.DOWN:
$AnimatedSprite2D.play("down_walk")
Vector2.LEFT:
$AnimatedSprite2D.play("left_walk")
func attacking():
is_attacking = true
play_anim() # Ensure attack animation starts immediately
var attack_animation_length = 0.5
await get_tree().create_timer(attack_animation_length).timeout
is_attacking = false
func player():
pass