How to wait the whole scene load to execute?

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

Every time i switch scenes or play my project some of the animations and stuff are already beeing executed in the background before the whole scene loads.

This makes the game start running before the player can even see whats happening… i wanna make godot wait for the whole scene to load before running anything, is there a simple way to do this? maybe some _on_load() method of something :S

:bust_in_silhouette: Reply From: Sween123

Load the worlds first, by that I mean first load all the scenes and all the infos and then start the scene you want to start. Have a function start() or open() in your scenes, you can also add stop(), close(), delete(), etc if you want. When you load, just run the loading functions, when loading is finished, call start(). (You may use the property “visible” to open or hide a scene)

:bust_in_silhouette: Reply From: CathodeRayBlues

I’ve encountered a similar problem and have done lots of testing to figure out how this happens. So far my lead is that once certain nodes are both “ready” and set visible (in my case, a 3d scene), the entire game hangs for a second or two before displaying it.

I got around this by using yield funtions and timers between loading certain parts of the scene and before playing animations (I’m using C# so the example code will be using async methods and the await ToSignal() function instead).
The code should look something like this

public override void _Ready()
{
	InitializeMap();
}
async void InitializeMap() 
{
	PackedScene startupScene = 
    (PackedScene)ResourceLoader.Load(sceneDir);
    Spatial newMap = (Spatial)startupScene.Instance();
    //loading the map file
    await ToSignal(GetTree().CreateTimer(0.01f), "timeout"); 
    //first timer
	AddChild(newMap);//then add map to scene tree
	await ToSignal(GetTree().CreateTimer(0.001f), "timeout");
	//second timer
	AnimationPlayer.Play("startup"); //then startup animation plays
}
:bust_in_silhouette: Reply From: CharlesMerriam

You wait until frames are processed. This handles cases where other scenes, not direct descendants, are setting up global variables and areas where initial set-up would cause spurious events to fire.

Here’s, approximately, the code (as in this answer:

var Skeleton
 # called when this scene is loaded
 def _ready():
       ...
       self.call_deferred("_started")

 # called when all scenes are loaded
 def _started():
      Skeleton = my_global_vars.Skeleton
      # connect to signals only after everything is initialized
      Skeleton.connect("broken_bone", self, "on_broken_bone")