Reputation: 67
The problem: There are two scenes: a loading scene and a play scene. The loading scenes does the heavy lifting setup for the play scene and loads the play scene. The play scene is supposed to take that data and reconstitute it on the other side. The play scene appears to not be firing the ready signal and the level reconstruction method is in turn not being called.
So, I created a simple Godot project and was able to replicate the behavior with two simple Node3D scenes each with a small script attached.
SceneOne.cs
using Godot;
public partial class SceneOne : Node3D
{
[Export]
private string _SceneTwoPackedPath;
private PackedScene _SceneTwoPacked;
public override void _Ready()
{
_SceneTwoPacked = ResourceLoader.Load<PackedScene>(_SceneTwoPackedPath);
GD.Print("Scene 1 In Ready");
GetTree().Root.Ready += Setup;
GD.Print("Scene 1 Almost Ready");
}
public override void _Process(System.Double delta)
{
GD.Print("Scene 1 Processing");
}
public void Setup()
{
GD.Print("Scene 1 Ready");
GD.Print("Scene 1 In Setup");
//GetTree().ChangeSceneToPacked(_SceneTwoPacked);
}
}
SceneTwo.cs
using Godot;
public partial class SceneTwo : Node3D
{
[Export]
private PackedScene _SceneOnePacked;
public override void _Ready()
{
GD.Print("Scene 2 In Ready");
GetTree().Root.Ready += Setup;
GD.Print("Scene 2 Almost Ready");
}
public override void _Process(double delta)
{
GD.Print("Scene 2 Processing");
}
public void Setup()
{
GD.Print("Scene 2 Ready");
GD.Print("Scene 2 In Setup");
GetTree().ChangeSceneToPacked(_SceneOnePacked);
}
}
I then set the main scene to scene one, and hit play, and as similarly to my game I get this debug window:
Godot Engine v4.2.2.stable.mono.official.15073afe3 - https://godotengine.org
Vulkan API 1.3.242 - Forward+ - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce RTX 3060
Scene 1 In Ready
Scene 1 Almost Ready
Scene 1 Ready
Scene 1 In Setup
Scene 2 In Ready
Scene 2 Almost Ready
Scene 2 Processing
Scene 2 Processing
Scene 2 Processing
Scene 2 Processing
...
So, this behavior is perhaps correct? For me I find it undesirable and inconsistent. I would want Scene 2 to fire ready and call the setup, ideally not running _Process/_PhysicsProcess until setup is finished (I know there are ways to do that i.e. SetProcess) but at least getting to the setup function. I think I can work around this if I need to, but I want to understand why this is happening, as Godot is the engine I will be using for this project and high likely for other projects in the future.
Thank you,
Some extra context: Working on implementing level randomization and decided to implement a loading scene that will compute a dynamic level, transfer the data into a singleton, and load a generic level scene. That generic level scene in turn reconstitutes the level verbatim from the singleton. I acknowledge now that this is probably needlessly complicated, but the motivation was to in theory front load the processing in another scene to free up the main scene to start quickly. Considering moving to more of a single scene, "pause the simulation" with a loading splash sort of approach.
Upvotes: 0
Views: 60
Reputation: 67
The solution was change the ready signal to be on the second scene object itself and not on the root. What we learned here was that when the scene changes the root remains, so it doesn't get ready called on it again. By setting the function to be called after ready on the second scene object itself and not the root the Setup function gets called. Probably should change the first scene object to call on itself too.
This was tested in my actual project and not here, but it should work.
using Godot;
public partial class SceneTwo : Node3D
{
[Export]
private PackedScene _SceneOnePacked;
public override void _Ready()
{
GD.Print("Scene 2 In Ready");
Ready += Setup; //Instead of GetTree().Root.Ready
GD.Print("Scene 2 Almost Ready");
}
public override void _Process(double delta)
{
GD.Print("Scene 2 Processing");
}
public void Setup()
{
GD.Print("Scene 2 Ready");
GD.Print("Scene 2 In Setup");
GetTree().ChangeSceneToPacked(_SceneOnePacked);
}
}
Upvotes: 0