AnimationPlayer2D freezes after second time being played

Godot Version

Godot4

Question

I’m creating a CanvasLayer node with label,animationplayer and color rect to use as a screen notification for when a boss is spawned and defeated.

The CanvasLayer node is called BossNotifScreenUI and has a function to set label text and a function to “post” a notification, when called this post function,pauses scene tree, calls a function to hide the boss health bar, plays animation “in” which changes the alpha of the modulate for both label and color rect.

On spawn the code works fine but once i call again on boss death, using signals which I’ve tested to be working it freezes just after playing the “in” animation. i have the animation player process set to always

boss_notif_screen_ui.gd script

extends CanvasLayer

@onready var label = $Label
@onready var animation_player = $AnimationPlayer
@export var boss_health: CanvasLayer

var info: String = ""

func _ready():
	set_visible(false)


func set_label_text(text:String):
	info = text

func post_notification():
	pause_tree(true)
	set_visible(true)
	#print("step2")
	label.text = info
	#print(info)
	animation_player.plady("in")
	#print("step3")
	await get_tree().create_timer(1).timeout
	#print("step3.5")
	animation_player.play("out")
	await get_tree().create_timer(.2).timeout
	pause_tree(false)
	set_visible(false)
	



func pause_tree(value:bool):
	get_tree().paused = value

func change_health_visibility(value:bool):
	boss_health.visible = value

swan.gd boss script

extends CharacterBody2D

@onready var health_component: HealthComponent = $HealthComponent
@onready var visuals = $visuals
@onready var velocity_component = $VelocityComponent
@onready var attack_timer = $AttackTimer
@onready var animation_player = $AnimationPlayer
@onready var collision = 	$CollisionShape2D
@onready var boss_health_ui = $BossHealthUi
@onready var health_bar = $BossHealthUi/HealthBar
@onready var sprite_2d = $visuals/Sprite2D
@onready var walk_animation = $WalkAnimation
@onready var boss_notif_screen = $BossNotifScreen


@export var boss_name: String
var stopped = false

func _process(delta):
	if ! stopped :
		move_to_player()
		walk_animation.play("walk")
	if velocity.x < 0:
		sprite_2d.flip_h = true
	else:
		sprite_2d.flip_h = false





func _ready():
	health_component.health_bar = health_bar
	boss_notif_screen.set_label_text(boss_name + " Has Spawned")
	boss_notif_screen.post_notification()
	#boss_notif_screen.set_self_visible(true)
	update_health_display()
	health_component.health_changed.connect(on_health_changed)
	health_component.died.connect(on_death)
	
	#change_collision(true)
	


func move_to_player():
	velocity_component.accelerate_to_player()
	velocity_component.move(self)

func on_health_changed():
	update_health_display()

func on_death():
	boss_notif_screen.set_label_text(boss_name + " Has Been Defeated")
	boss_notif_screen.post_notification()


func update_health_display():

	health_bar.value = health_component.get_health_percent()

func _on_attack_timer_timeout():
	animation_player.play("charge")

func change_collision(value):
		collision.set_disabled(value)

func stop(timer:float = 0.0):
	if timer == 0.0:
		stopped = true
	else:
		stopped = true
		await get_tree().create_timer(timer).timeout
		

func restart():
	stopped = false

func _on_charge():
	change_collision(true)
	stop(4.5)
	velocity_component.lunge(self)
	restart()
	change_collision(false)

Does anyone know how i can fix this or do it better?

at first u have a mistake in the 22 line you typed plady in the boss_notif_screen_ui.gd script and if you stop playing one animation and start other and want to play the first one again try to use animation_player.queue(“in”) i think that could work :slight_smile: