From f17a8be3d2b2fb496b010a81edaa6a97581f6dd3 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 9 Oct 2024 17:33:22 +0200 Subject: [PATCH] SimpleSpawner: Allow spawning nodes as child of scene In the current implementation, spawned nodes are children of the spawner. In some cases this behaviour is what you want, but it means it's not possible to change the spawn position of future scenes without moving already-spawned scenes. Add a new property to SimpleSpawner which allows choosing a new mode where spawned scenes are made children of the root scene. The change in spawn_start() is necessary because, if the Start Spawning block is used in the On Ready entrypoint, this results in spawn_start() being called from the SimpleSpawner's _ready() function. At this point, the SimpleSpawner itself is ready but the root scene is not. In this case, attempting to add a child to the root scene logs an error, and a later attempt to get the spawned scene's parent to remove it returns undefined. --- .../simple_spawner/simple_spawner.gd | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/addons/block_code/simple_spawner/simple_spawner.gd b/addons/block_code/simple_spawner/simple_spawner.gd index e3a53892..fac71698 100644 --- a/addons/block_code/simple_spawner/simple_spawner.gd +++ b/addons/block_code/simple_spawner/simple_spawner.gd @@ -7,11 +7,20 @@ const BlocksCatalog = preload("res://addons/block_code/code_generation/blocks_ca const OptionData = preload("res://addons/block_code/code_generation/option_data.gd") const Types = preload("res://addons/block_code/types/types.gd") +enum SpawnParent { + THIS, ## Spawned scenes are children of this node + SCENE, ## Spawned scenes are children of the scene +} enum LimitBehavior { REPLACE, NO_SPAWN } ## The scenes to spawn. If more than one are provided, they will be picked randomly. @export var scenes: Array[PackedScene] = [] +## The node that the spawned scenes should be a child of. If you want to move +## the SimpleSpawner without moving the scenes it has already spawned, choose +## SCENE. +@export var spawn_parent: SpawnParent + ## The period of time in seconds to spawn another component. If zero, they won't spawn ## automatically. Use the "Spawn" block. @export_range(0.0, 10.0, 0.1, "or_greater") var spawn_frequency: float = 0.0: @@ -41,7 +50,7 @@ func get_custom_class(): func _remove_oldest_spawned(): var spawned = _spawned_scenes.pop_front() if is_instance_valid(spawned): - remove_child(spawned) + spawned.get_parent().remove_child(spawned) func _set_spawn_fraquency(new_frequency: float): @@ -60,7 +69,7 @@ func spawn_start(): _timer.wait_time = spawn_frequency _timer.timeout.connect(spawn_once) _timer.start() - spawn_once() + spawn_once.call_deferred() func spawn_stop(): @@ -90,7 +99,12 @@ func spawn_once(): var scene: PackedScene = scenes.pick_random() var spawned = scene.instantiate() _spawned_scenes.push_back(spawned) - add_child(spawned) + match spawn_parent: + SpawnParent.THIS: + add_child(spawned) + SpawnParent.SCENE: + get_tree().current_scene.add_child(spawned) + spawned.position = global_position func do_set_spawn_frequency(new_frequency: float):