How to revert to the idle animation after playing a hurt animation?

Godot Version

4.3

Question

How would I play the hurt animation once and then switch back to the idle animation? Right now the game starts in the hurt animation an only plays the idle animation after the player takes damage.

extends CharacterBody2D

var decelerate_on_jump_realease = 0.5
var walk_speed = 150.0
var run_speed = 200.0
var acceleration = 0.1
var jump_force = -400.0
var deceleration = 0.1
var health = 4
var hit_by_enemy = false
var time_in_seconds = 0.5
var gravity = ProjectSettings.get_setting(“physics/2d/default_gravity”)

func _on_ready():
if hit_by_enemy == false:
$AnimatedSprite2D.play(“idle”)

func _physics_process(delta):
# Gravity.
if not is_on_floor():
velocity.y += gravity * delta

# Jumping.
if Input.is_action_just_pressed("jump") and is_on_floor():
	velocity.y = jump_force
if Input.is_action_just_released("jump") and velocity.y < 0:
	velocity.y *= decelerate_on_jump_realease
	
#Running.
var speed
if  Input.is_action_pressed("run"):
	speed = run_speed
else:
	speed = walk_speed

#Left/Right movement.
var direction := Input.get_axis(“left”, “right”)
if direction:
velocity.x = move_toward(velocity.x, direction * speed, walk_speed * acceleration)
else:
velocity.x = move_toward(velocity.x, 0, walk_speed * deceleration)
move_and_slide()

func hit(posx):
hit_by_enemy = true
if hit_by_enemy == true:
$AnimatedSprite2D.play(“hurt”)
velocity.y = jump_force * 0.7
if position.x < posx:
velocity.x = 200
elif position.x > posx:
velocity.x = -200
$AudioStreamPlayer2D.play()
if hit_by_enemy == true and health>3:
health -= 1
$HUD/health_full.set_self_modulate(Color(0,0,0,0))
hit_by_enemy = false
elif hit_by_enemy == true and health>2:
health -= 1
$HUD/health_three_fourth.set_self_modulate(Color(0,0,0,0))
hit_by_enemy = false
elif hit_by_enemy == true and health>1:
health -= 1
$HUD/health_half.set_self_modulate(Color(0,0,0,0))
hit_by_enemy = false
elif hit_by_enemy == true and health>0:
health -= 1
$HUD/health_quarter.set_self_modulate(Color(0,0,0,0))
hit_by_enemy = false
if health == 0:
await get_tree().create_timer(time_in_seconds).timeout
get_tree().change_scene_to_file(“res://scenes/death_screen.tscn”)
elif hit_by_enemy == false:
$AnimatedSprite2D.play(“idle”)
Input.action_release(“left”)
Input.action_release(“right”)

I’m not sure where hit is called in your code or why the hurt animation is the default animation.

What you can do is listen for the hurt animation to finish and set the idle animation from the method you’ve connected to the signal. (This only works if the animation isn’t looping, but since it’s a hurt animation I assume it isn’t.)

Shouldn’t idle be default? Since at the top it should play while hit_by_enemy is false. Sorry if i may seem dumb I’m new to this. Also hit is called in the enemy hitbox code since you asked.

func _on_ready():
   if hit_by_enemy == false:
      $AnimatedSprite2D.play(“idle”)

_on_<name> is a convention for methods that connect to signals. But I assume that in this case, you probably meant to use func _ready()->void. _ready is called when the scene enters the tree and would cause the animation to play.

Alright, I changed it to what you suggested, I have the_on_animated_sprite_2d_animation_finished(): function but I have no idea what to do with it it if I’m being honest. Nevermind I figured it out! Thanks a ton I would be working on this for days if not for you.

1 Like

It’s not a function, it’s a signal. The signal is emitted once the animation finishes. You can connect a method to the signal. That way, the method is called when the signal is emitted. You could do something like this:

func _ready()->void:
   $AnimatedSprite2D.animation_finished.connect(play_new_animation.bind())

func play_new_animation()->void:
   if $AnimatedSprite2D.get_animation() == &"hurt":
      $AnimatedSprite2D.play("idle")
1 Like