0 votes

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 onSightRangebodyentered(body):
if body.isingroup("Player"):
state = ALERT
target = body
shoottimer.start()

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

func process(delta):
match state:
IDLE:
ap.play("Idle")
ALERT:
ap.play("Alert")
eyes.look
at(target.globaltransform.origin, Vector3.UP)
rotate
y(deg2rad(eyes.rotation.y * turn_speed))

func onShootTimertimeout():
if raycast.is
colliding():
var hit = raycast.getcollider()
if hit.is
in_group("Player"):
print("Hit!")

in Engine by (12 points)

1 Answer

0 votes

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.

by (7,742 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.