Animationtree statemachine issue - how do i stop animations in gdscript?

Godot Version

godot 4

Question

I’m trying my hand at a animation tree state machine but I’ve made a mistake somewhere along the line and I now have an issue. If the enemy dies while it’s in the attack animation it doesn’t play the death animation, but just disappears instead. This seems to be due to the “await animation finished” lines:

	while animation_tree["parameters/conditions/is_attacking"] == true:
		velocity.x = 0
		await animation_tree.animation_finished


func _on_start_attack_area_body_entered(body):
	if body.is_in_group("Player_body"):
		is_attacking = true
		animation_tree["parameters/conditions/is_attacking"] = true
		await animation_tree.animation_finished
		animation_tree["parameters/conditions/is_attacking"] = false

But when I try to remove them the entire code stops working

Any and all help is greatly appreciated

Code for skeleton enemy:

#things to do:
#1
	#Skeleton dead animation should interrupt attack animation
	#currently it dosent and skeleton disappears after attack animation is finished
#2
	#if player enters "start area attack shape" in the last frames when enemy isn't 
	#damaging the player, the skeleton won't attack again and will keep walking forward


extends CharacterBody2D

#-------------------------------------------
const speed = 50
#-------------------------------------------
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var chase = false
var is_attacking = false
#-------------------------------------------
@onready var player = get_node("../../Player/Player")
@onready var skeleton = $"."
@onready var animation_tree: AnimationTree = $AnimationTree
@onready var health = $Damageable_skeleton.Skeleton_health


func _on_ready():
	add_to_group("enemy")
	animation_tree.active = true

#func process differs from physics_process so as to maintain overview
func _process(_delta):
	update_animation_parameters()
	if is_attacking == false:
		$Attack_detection.monitoring = false
#adds skeleton to enemy group - only works this way for some reason
	if $".".is_in_group("enemy") != true:
		add_to_group("enemy")
	print(animation_tree["parameters/conditions/is_attacking"])

#skeleton physics and movement
func _physics_process(delta):
	if not is_on_floor():
		velocity.y += gravity * delta
	move_and_slide()
	var direction = (player.position - self.global_position).normalized()
	if chase == true:
		velocity.x = direction.x * speed
	if direction.x < 0:
		get_node("AnimatedSprite2D").flip_h = true
		$Attack_detection.scale.x = -1
		$Start_attack_area.scale.x = -1
	else:
		get_node("AnimatedSprite2D").flip_h = false
		$Attack_detection.scale.x = 1
		$Start_attack_area.scale.x = 1


#-------------------------------------------
# if player is in range skeleton will chase the player
func _on_detection_area_body_entered(body):
	if body.is_in_group("Player_body"):
		chase = true

func _on_detection_area_body_exited(body):
	if body.is_in_group("Player_body"):
		chase = false
		velocity.x = 0

#animation tree state machine code
func update_animation_parameters():
#movement animation
	if(velocity.x == 0):
		animation_tree["parameters/conditions/Idle"] = true
		animation_tree["parameters/conditions/is_moving"] = false
	elif(velocity.x != 0):
		animation_tree["parameters/conditions/Idle"] = false
		animation_tree["parameters/conditions/is_moving"] = true
#death animation
	if $Damageable_skeleton.Skeleton_health == 0:
		#figure out how to cancel all other animations before playing dead animation
		animation_tree["parameters/conditions/Dead"] = true
	if is_attacking == true and $Attack_detection.monitoring == true:
		Game.playerHP -= 3

#big issue in code below
	while animation_tree["parameters/conditions/is_attacking"] == true:
		velocity.x = 0
		await animation_tree.animation_finished

#attack animations
func _on_start_attack_area_body_entered(body):
	if body.is_in_group("Player_body"):
		is_attacking = true
		animation_tree["parameters/conditions/is_attacking"] = true
		await animation_tree.animation_finished
		animation_tree["parameters/conditions/is_attacking"] = false



func _on_start_attack_area_body_exited(_body):
	is_attacking = false


Animation tree setup:

If the enemy dies while it’s in the attack animation it doesn’t play the death animation, but just disappears instead

I don’t really see where the enemy is queue_free’d upon its HP reaching 0. Either way, if the enemy dies, then it should send out a signal that it is dying.

Either that or the enemy calls a function to stop whatever it is doing and trigger the death animation. Only when the death animation is finished, is it allowed to be queue_free’d.

The animationTree transition from Attack → Death should only be dependent on a boolean check. Once the enemy HP reaches zero, the boolean should be switched and the _physics_process() method should pick up on the boolean change immediately in order to stop the attack animation

I have the “taking damage” script inside another node that handles taking damage and dying

Code:

extends damageable

@export var Skeleton_health : int = 30
@onready var animation_tree: AnimationTree = $"../AnimationTree"


#skeleton health and damage
func hit(damage : int):
	if Skeleton_health != 0:
		Skeleton_health -= damage
		animation_tree["parameters/conditions/Hurt"] = true
		await animation_tree.animation_finished
		animation_tree["parameters/conditions/Hurt"] = false
	if Skeleton_health <= 0:
		get_parent().chase = false
		get_parent().velocity.x = 0
		Game.Gold += 5
		Utils.SaveGame()
		get_parent().collision_layer = 4
		get_parent().collision_mask = 4
		get_parent().queue_free()

func _physics_process(_delta):
	label.text = str(Skeleton_health)