Trouble with enemy "Hit" animation

Hello all! Beginner here with a bit of trouble playing an animation!

I’ve created a Player that, when attacks, creates a CollisionShape and a Goblin that has a CollisionShape. I have attempted to set it up so that when the Goblin takes a “Hit” from the Player it checks that the area entering is from the correct group (in this case “Sword”), then plays one of two animations depending on what the life_left variable is at.

The trouble I’m having is that the “Hit” animation is not playing, but the “Death” animation does after the appropriate amount of hits. I’ve double checked the Hit animation and it is set up correctly (no autoplay or loop). My first thought is maybe the Idle animation is overriding the Hit animation. But then why does the Death animation still play?

Is this a situation where you would want to set up a Boolean like var is_hit to regulate the process? Here is my Goblin script:


@onready var goblin_sprite = $AnimatedSprite2D

var life_left = 3
var dead = false

func _process(delta):
	if not dead:
		goblin_sprite.play("Idle")

func _on_area_entered(area):
	if area.is_in_group("Sword"):
		if life_left > 0:
			goblin_sprite.play("Hit")
			life_left -= 1
		else:
			goblin_sprite.play("Death")
			dead = true

func _on_animated_sprite_2d_animation_finished(): 
	if goblin_sprite.animation == "Death":
		queue_free()

I appreciate any and all help anyone can provide. Going through the process of learning Godot has been a blast.

Correct. You’re calling goblin_sprite.play("Idle") in _process, i.e. every frame.

Because you set dead = true when the player runs out of lives and only play the idle animation as long as the player is not dead.

That would solve the problem, but doesn’t scale well. As long as none of your animations loop, it should be enough to simply check if the AnimatedSprite2D
is currently playing an animation before triggering the idle animation:

func _process(delta):
    if not (dead or goblin_sprite.is_playing()):
        goblin_sprite.play("Idle")
1 Like

Thank you for the informative response. I completely forgot that the _process meant every frame. I will also use:

func _process(delta):
    if not (dead or goblin_sprite.is_playing()):
        goblin_sprite.play("Idle")

going forward. That strikes me a a very clean bit of code.

Thank you again! It’s very much appreciated!