Load/preload a tscn but not instance it.

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

I have a scene that contains multiple enemies. I call it enemyfactory.
Structure is

enemyfactory node [script to duplicate enemy node below and return it]
enemy1node [enemy1control script]
enemysprite
enemy2node [enemy1control script]
enemysprite

This works great, I can call enemyfactory to spawn a new enemy.
I do the same for bullets and other things there are many of.

But the problem I’m having is that when the enemyfactory scene is loaded in via preload in global.gd singleton, the enemy1node, enemy2node, are instanced initially.

Here’s the call in global.gd: enemyfactory = preload(“res://enemies/enemyFactory.tscn”)

I tried load and preload.

I don’t want this behavior to happen. Is there a way to prevent it?

I want to load a tscn into a variable and NOT instance and of its contents right away. Is this possible?

:bust_in_silhouette: Reply From: njamster

I want to load a tscn into a variable and NOT instance and of its contents right away. Is this possible?

Simply instance the child-nodes from script once you need them?

:bust_in_silhouette: Reply From: EmanuelOzorio

I usually do this:
create a var to preload the factory
create a var that represents the factory and instance the preload.
When I need to get a child of the factory I add the child of the factory as a child node of the main node with the duplicate function.

works fine for me.

Example:

const pre_enemy_factory = preload("res://src/enemyfac.tscn")
var enemy_factory
func _ready():
  enemy_factory = pre_enemy_factory.instance()

func add_enemy:
  var enemy = enemy_factory.get_child("your enemy").duplicate()
  level.add_child(enemy)

So then it seems like my code has a bug that my preload seems to be instancing them on its own - preload does not have instancing as default behavior, so my code must be doing it somewhere.

ryanscott | 2020-05-04 15:49

Seems like the problem is where you put the code.
You mentioned that the code is in your global singleton. Maybe that is the problem.
Try to instante the factory in the script of your level, for example. If you have more levels try to create a script base and extend other Scripts from this.

P.S.: Sometimes when are no scenes, or especific nodes, open in editor the autocomplete does not work. Try to code the .instance() and run project to check if works.

EmanuelOzorio | 2020-05-04 16:12

I isolated the problem.

gameover.tcsn comes up after the player dies, and it shows a bunch of enemies and bullets.

	if($"/root/global".playerhealth < 1):
	print("player dead")
	get_tree().change_scene("res://TITLES/gameover.tscn")   
else:
	global.play_sound("hurtplayer", false, global_transform.origin)
print("coming out of hurtplayer")

Even though it says scene change, it still ends up printing(“coming out of hurtplayer”) - this is in player.gs. There’s only 1 player.

Why doesn’t it just completely switch the entire scene tree? it seems it switches just the player scene, how do i make it change root scene?

ryanscott | 2020-05-04 16:26

I think that when godot change the scene by default functions (change_scene or change_scene_to) his kill the previously scene with queue_free(). If I’m correct, the scene only will terminate when all of the tasks are done and is safe to free the sceene.
I think that you must end the objects that are processing in the scene before change it.

Its hard to see the problem without the source, but i hope that’s was help.

EmanuelOzorio | 2020-05-04 19:32