0 votes

Hello,
I'm trying to create an explosion that is to be spawned in after an enemy dies.
The explosion is a Node2D object and comprises an animated sprite "ExplosionSprite", an audio stream "SoundExplosion01" and a timer "DeathTimer".

Here is the code for spawning the explosion. It is executed within the enemy.

export (PackedScene) var death #the explosion is a scene, placed here
var health = 5

func enemy_handle_hit(): #this is triggered when a bullet hits the enemy
    health -= 3
    if health <= 0:
        var explosion = death.instance()
        add_child(explosion)
        queue_free()

This is the code of the explosion:

extends Node2D

onready var explosion_sprite = $ExplosionSprite
onready var explosion_sound = $SoundExplosion01
onready var death_timer = $DeathTimer

func _ready():
    print(str(get_global_position().x, ", ", get_global_position().y)) #debug
    death_timer.start()
    explosion_sprite.play()
    explosion_sound.play()

func _on_DeathTimer_timeout():
    print("dead") #debug
    queue_free()

So here's what happens: the explosion spawns in and the print() under _ready() is called and provides the proper coordinates. However, the timer does not start and neither the sprite nor the audio ever play.
Also, when I set timer, sprite or audio to autoplay in the Inspector, they never start either when the scene is instanced. However, when I play the actual scene using the "Play Scene" button, it works fine.
Before anyone asks, the on_DeathTimer_timeout() is connected, but even if it wasn't, the sprite and audio should play nontheless.
There is no error logged, it's just like the thing is ignoring the start() and play() commands.

What is also weird, I have another object extending Area2D that also starts a timer in _ready() and that works fine.
Is it different with Node2D? Do I need to do that stuff in another function?

Godot version 3.3.3
in Engine by (31 points)
edited by

1 Answer

0 votes
Best answer

It looks like it’s because the enemy is calling queuefree() to fast for the explosion to be able to happen. To solve this you could use getparent().addchild() instead of just addchild(). Alternatively, you could have a timer the length of the explosion and call queue_free() when it times out.

by (51 points)
selected by

Oh... my god... I never considered that if I delete an object, the child objects get deleted as well. Wow, I am such an idiot.
get_parent().add_child() is the solution.
Thanks thadiusII!

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.