← Pixel Dreamer Studio

Remove a one-shot particle effect when it ends

Connect finished to queue_free, then call restart() after add_child.

Connect finished to queue_free, then call restart() after add_child(). In our tests, a one-shot effect added without that restart() never fired finished, so the node stayed in the scene.

Three bursts of soft particles in orange, blue and purple in Godot 4.7
Three one-shot bursts from the script below, 0.4 seconds after they spawned.

The code

extends Node3D
## Spawn a one-shot effect from a scene and remove it when it ends.

@export var effect: PackedScene

func spawn_effect(at: Vector3) -> GPUParticles3D:
	var fx := effect.instantiate() as GPUParticles3D
	add_child(fx)
	fx.global_position = at
	fx.finished.connect(fx.queue_free)
	fx.restart()  # start it now, so finished always fires
	return fx

We spawned 200 effects with this function, each with a lifetime of 0.4 seconds. After 1.5 seconds, none were left in the scene.

Why restart() is needed

We added a one-shot effect with add_child() alone, once as a new node and once from a PackedScene, then waited more than three times its lifetime. finished fired 0 times in both cases. The same kind of node fired it once after restart().

An effect made of several emitters

extends Node
## For an effect made of several one-shot emitters: free the root after the last one ends.

func play_and_free(root: Node) -> void:
	var parts := root.find_children("*", "GPUParticles3D", true, false)
	var left := [parts.size()]  # an array: a lambda keeps its own copy of a plain int
	for p in parts:
		p.finished.connect(func():
			left[0] -= 1
			if left[0] == 0:
				root.queue_free())
		p.restart()

Every emitter under the root must be One Shot, because a looping emitter never fires finished.

Do not check emitting to see if an effect has ended. With Explosiveness at 1, it was already false 0.1 seconds into a 0.4 second effect. Our first version of this script did that and freed the effect too early.

Tested in Godot 4.7 with the Compatibility renderer.

Want ready-made effects? Try the free Arcane VFX pack or the VFX Collection for Godot 4.