How do i make a 3D enemy "Die"?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dingus04

So i followed Garbaj’s Enemy AI 1 and 2 and i now want to make the enemy have a death thing

The Enemy scene has an instance of the model scene and the model scene has the anim player and this script;

extends KinematicBody

var health = 100
onready var AP = $AnimationPlayer
#onready var dt = $Death
func _process(delta):
if health <= 0:
queue_free()

When queue_free happens i get;
Attempt to call function ‘play’ in base ‘previously freed instance’ on a null instance.
On the scene of the enemy here is all of its code;
extends Spatial

enum{
IDLE,
ALERT,
Dead,
}

var state = IDLE

var target

#var health = 2

const turn_speed = 2

onready var raycast =$RayCast
onready var ap = $dummymale/AnimationPlayer
onready var eyes = $Eyes
onready var shoottimer = $ShootTimer

func _on_SightRange_body_entered(body):
if body.is_in_group(“Player”):
state = ALERT
target = body
shoottimer.start()

func _on_SightRange_body_exited(body):
state = IDLE
shoottimer.stop()

func _process(delta):
match state:
IDLE:
ap.play(“Idle”)
ALERT:
ap.play(“Alert”)
eyes.look_at(target.global_transform.origin, Vector3.UP)
rotate_y(deg2rad(eyes.rotation.y * turn_speed))

func _on_ShootTimer_timeout():
if raycast.is_colliding():
var hit = raycast.get_collider()
if hit.is_in_group(“Player”):
print(“Hit!”)

:bust_in_silhouette: Reply From: Inces

Immediate queue free is not the good way to handle dying. It is prone to massive amount of errors, as a lot of other game events depend on your objects behavior, and if object suddenly disappears these events will be interrupted. It is good practice to at least create a separate state for object in process of dying. When hp drops to zero enforce this state upon enemy, and this is enough to prevent all other behaviors in other states, along with your play() animation. I advise to give some time in this dying state, before queuing free enemy, so in setget state machine make it - if new state is DYING - await some dynamical timer timeout and then queue_free. When the game becomes really complicated, queuing free after defeating enemy becomes impossible. Often it is better to change the state of enemy to CORPSE, turn off performance expensive processes and let it live in sleeping state, and only after level ends queuing free all corpses.