+1 vote

I have a function to swap scenes in a singleton

func change_scene(scene):
  get_tree().change_scene("res://Scenes/MainScenes/%s"%scene)

But I want to add a CanvasLayer on every new Scene which I'm using it as a Debugger Overlay.
To add it as a child of the loaded scene I have a function on every Scene Main node

func _ready():
  Scenes_Manager.add_debug_overlay(get_path())

-At Scene_Manager singleton

func add_debug_overlay(path):
  var DebugOverlay = load("res://Scenes/DebugOverlay.tscn").instance()
  get_node(path).add_child(DebugOverlay)

This requires me to create an script on scene and add this function.

I was trying to simplify this process using function and calling it in change_scene after the change_scene()

func get_scene_info():
  var scene_tree = str(get_tree().get_current_scene())
  var scene_name =str(get_tree().get_current_scene().get_name())

But what I get is the info of the last scene instead of the new one.
What would be a solution to this problem? Is there something I can use to tell when the next scene is ready and access that information from the singleton?

I know I could just add the CanvasLayer.tscn in every scene in the editor but I would like to understand better how this process works

in Engine by (235 points)

1 Answer

+1 vote
Best answer

Hey!, you could try using the ResourceInteractiveLoader

Or combining yield and assert:
https://youtu.be/_4_DVbZwmYc
https://youtu.be/nFcBSuzxFdM

I'm just giving you some ideas off the top of my head, but I hope this can give you a kickstart in the right direction.

by (71 points)
selected by

I didn't read much about yield but I discarded it because I thought the result would be the same, I would need a script on the new scene to emit a signal to let me know the scene is loaded or I would have to set a delay but I don't know how much time this process needs it could take several seconds or not even one.

ResourceInteractiveLoader Seem like what I was looking for it comes with handy methods to collect the info I was looking for from all inside the Singleton Script.

and since I don't have anything huge or a macro manage the load I can use

Error ResourceInteractiveLoader::wait();

Various questions about Loading in stages:
The _process(time) function has time instead of delta I read that you usually use delta to measure time then why time here?.

The documentation shows a while loop to keep using the poll() method
and a comment explains that the var time_max is blocking the thread for 100ms

func _process(time):
var t = OS.get_ticks_msec()
while OS.get_ticks_msec() < t + time_max:

But I cant understand how, if the var t is set before the while loop t + time_max is always gonna be bigger than OS.get_ticks_msec() right? so how is it blocking blocking the thread for 100ms? am I missing something?

hey! it's nice to know ResourceInteractiveLoader helped.

About _process(time) I believe that is what delta used to be called on previous versions. You can actually call it whatever you want: time, delta, _delta, d. The thing is that the first argument of _process() will always return the elapsed time between frames.

About:

var t = OS.get_ticks_msec()
while OS.get_ticks_msec() < t + time_max:

That is a while loop, so it's repeating the code infinitely until one of three conditions is met:

  • Loading is finished
  • An error occurred while loading
  • OS.getticksmsec is more than t + time_max

Now, the catch is that t is not a reference, it is a value. So whatever OS.getticksmsec() is at that moment will get stored as a number, for example t = 100. At the end of the while loop, the condition gets re-evaluated and now OS.getticksmsec() has changed but t remains the same, 100.

It's very tricky to get, but the key element is that the combination of t equals a value (not OS.getticksmsec()) and the while loop gives you the desired blocking effect.

It also seems that the poll action can take one or more frames to retrieve the information, that's why OS.get_ticks_msec() changes after each loop cycle, and t remains the same.

I think I get it know _process is called every frame and in that time the ticks on the computer keep adding in. I'll keep reading the documentation since loops and the priority some functions have over others are concepts still hard to grasp for me.

Thanks a lot AlbGD much appreciated!

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 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 webmaster@godotengine.org with your username.

Categories