Animating an attack in 2D

Godot Version

Godot v4.5

Question

` Hi! I’m currently working on a small project, which is a simple 2D platformer game. Unfortunately, I couldn’t find any helpful articles that could aid me in animating an attack for my character. Here’s the problem: I have written a couple very basic lines of code, but I can’t get my attacking animation to play to the end before it is interrupted by my idle animation. For the record, I’m using “animated_sprite.play” (sprite frames) for my animations and my code for my animations is as follows:

if Input.is_action_just_pressed(“attack 2 (1)”):
animated_sprite.play(“attack”)

if direction == 0:
animated_sprite.play(“idle”)
else:
animated_sprite.play(“run”)

Sorry for any poor formatting, any help is appreciated! I am completely new to coding and I have NO idea how to use the animation player/animation tree. Thank you in advance!!`

Are you calling this code from the _physics_process() callback? I will assume yes.
That means that when you press you attack key, the animation starts playing, but then right after it is being replaced by either idle or run animations, because there are no checks in your code for if the attack animation is playing or not. One way to fix it would be to check for animated_sprite.is_playing() before you change your animation.

func _physics_process(_delta: float) -> void:
	if Input.is_action_just_pressed(“attack 2 (1)”):
		animated_sprite.play(“attack”)
	
	if not animated_sprite.is_playing():
		if direction == 0:
			animated_sprite.play(“idle”)
		else:
			animated_sprite.play(“run”)

You might also read about implementing a state machine. This might be an overkill for a small project like yours, so you need to judge for yourself if that is something worth implementing.

Thank you so much! I can not explain how much I appreciate your help!! One more thing, however, I for some reason can’t get my running animation to play again. The idle animation and running animation is perfect, but he doesn’t seem to run.
Thank you so much anyway!

Can you share your full code where you assign some value to a direction variable? There probably is an issue with this variable.
You can also add some print(direction) statements into your code to understand what’s the value of this variable at all times, should help you pin-point the problem.

  1. (This somewhat depends on how long your animations are:)
    If you only check for animated_sprite.is_playing(), “run” animation can’t overwrite “idle” animation (neither the other way around). So you should also check which animation is playing, and only prevent other animations when the current animation is “attack”.

  2. I’m assuming direction is using float values? You should use is_zero_approx(direction) then to check if it’s 0.

I’m not totally sure what it is you’re looking for, but I’ve attached an extract of my code.

Get the input direction: -1, 0, 1

var direction := Input.get_axis("ui_left", "ui_right")

# Flip the sprite
if direction > 0:
	animated_sprite.flip_h = false
elif direction < 0:
	animated_sprite.flip_h = true

#Play animations



if Input.is_action_just_pressed("attack 2 (1)"):
	animated_sprite.play("attack")

if not animated_sprite.is_playing():
	if direction == 0:
		animated_sprite.play("idle")
	else:
		animated_sprite.play("run")

#Apply movement
if direction:
	velocity.x = direction * SPEED
else:
	velocity.x = move_toward(velocity.x, 0, SPEED)