Godot Version
4.4.1
Question
I just started game development and coding less than a week ago and I don’t really know what I’m doing. I’m trying to make an attack animation play when I hit a certain button, but the character does a weird small movement before going back to idle.
func attack():
if Input.is_action_just_pressed(“attack”):
animated_sprite_2d.play(“Attack”)
Global.player_current_attack = true
attack_ip = true
$deal_attack_timer.start()
I tried following a tutorial and this was the best I could write without getting many errors… I’m so new to this, please help
also the indentations are not showing up here but I do have them in my script.
Use triple tick marks ``` above and below your code to format it:
func attack():
if Input.is_action_just_pressed(“attack”):
animated_sprite_2d.play(“Attack”)
Global.player_current_attack = true
attack_ip = true
$deal_attack_timer.start()
It’s not clear from this whether you are calling other animations elsewhere in the code. Like, if you are doing animated_sprite_2d.play("Idle")
in func _process(delta)
, for example, that would explain the issue here. Can you share more of the code?
Also, this code makes me wonder: when and where do you call attack()
? I feel like you should be checking whether the attack button has just been pressed, and if so, call attack()
, not the other way around. That in itself won’t cause the issue you’re having here, but it’s sort of backwards IMO
#Play Animations
if is_on_floor():
‘’'if direction == 0:
‘’'animated_sprite_2d.play(“Idle”)
‘’'else:
‘’'animated_sprite_2d.play(“Run”)
‘’'else:
‘’'animated_sprite_2d.play(“Jump”)
Oops, it didn’t format my code again, sorry!
Let me know if you need more.
Yep, that explains it: since you’re calling animated_sprite_2d.play("some_animation")
in _process(delta)
, and since _process(delta)
runs every frame, essentially what’s happening is every frame you’re interrupting whatever animation is happening and starting a new animation, depending on whether the character is on the floor standing still, on the floor moving, or in the air.
A quick band-aid to get the attack animation to work here is: (noticing you’re already setting Global.player_current_attack = true
in func attack()
):
in func _process():
if not Global.player_current_attack:
if is_on_floor():
if direction == 0:
animated_sprite_2d.play("idle")
etc
This should fix the issue since you simply won’t run the code that plays different animations if Global.player_current_attack
is true
. Notice though, that somewhere in your code you’ll need to set player_current_attack
to false once the attack is finished.
Also, if you add more animations, you’ll have all sorts of convoluted logic like “if the sprite is in the air and moving right but facing left and just finished attacking, play this animation, otherwise if the sprite is in the air and moving right and facing right and just started a double jump, play that animation, etc”. Feel free to keep adding complexity here until it gets a bit much - and when that happens, you can look into the “State Machine” pattern, which Godot has some built-in tools to help with setting up.