The Godot Q&A is currently undergoing maintenance!

Your ability to ask and answer questions is temporarily disabled. You can browse existing threads in read-only mode.

We are working on bringing this community platform back to its full functionality, stay tuned for updates.

godotengine.org | Twitter

0 votes

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?

in Engine by (36 points)

2 Answers

0 votes

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?

by (10,634 points)
+1 vote

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)
by (171 points)

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.

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.

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?

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.

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.