Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | goodymind |
So I followed the Background Loading Tutorial and managed to make it work in C#.
but when I try to change scenes like this
Main Menu > Simulation > Main Menu >(error) X Simulation
I was not able to get to the simulation for the second time, and this shows up in the error menu…
E 0:00:45.260 load_interactive: Resource: 'simulation.tscn' is already being loaded. Cyclic reference?
I don’t have a reference to the simulation, just a dictionary with its name and path. Any help?
This is in C#
The Autoload/Simulation Selector
using Godot;
using System;
namespace PhySim.simulations
{
public class SimulationSelector : Node
{
ResourceInteractiveLoader loader;
int wait_frames;
ulong time_max = 100; //ms;
public Node CurrentScene;
public override void _Ready()
{
SetProcess(false);
}
public void Return()
{
//the name of the root node of the simulation is Node
if (CurrentScene.Name == "Node")
{
GoToScene("res://MainMenu.tscn");
}
else
{
GetTree().Quit();
}
}
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("ui_cancel"))
{
Return();
}
}
public void GoToScene(string path)
{
loader = ResourceLoader.LoadInteractive(path);
if (loader == null)
{
GD.Print("error");
return;
}
SetProcess(true);
CurrentScene.QueueFree();
GetNode<AnimationPlayer>("AnimationPlayer").Play("loading");
wait_frames = 10;
}
public override void _Process(float delta)
{
if (loader == null)
{
SetProcess(false);
return;
}
if (wait_frames > 0)
{
wait_frames -= 1;
return;
}
var t = OS.GetTicksMsec();
while (OS.GetTicksMsec() < t + time_max)
{
var err = loader.Poll();
if (err == Error.FileEof)
{
var resource = loader.GetResource();
loader = null;
SetNewScene(resource);
break;
}
if (err == Error.Ok)
{
UpdateProgress();
}
else
{
GetTree().Quit();
loader = null;
break;
}
}
}
private void SetNewScene(Resource resource)
{
GetNode<AnimationPlayer>("AnimationPlayer").Stop();
GetNode<Control>("CanvasLayer/Control").Visible = false;
CurrentScene = (resource as PackedScene).Instance();
GetNode("/root").AddChild(CurrentScene);
}
private void UpdateProgress()
{
}
}
}
And the Main Menu Scene
using Godot;
using PhySim.simulations;
using System.Collections.Generic;
namespace PhySim
{
public class MainMenu : Control
{
private SimulationSelector SimSelector => GetNodeOrNull<SimulationSelector>("/root/SimulationSelector");
[Export(PropertyHint.MultilineText)] private Dictionary<string, string> Simulations;
private Dictionary<int, string> IDToPath;
private ItemList SimulationList => GetNodeOrNull<ItemList>("SimulationList");
public override void _Ready()
{
SimSelector.CurrentScene = this;
IDToPath = new Dictionary<int, string>();
int id = 0;
foreach(var pair in Simulations)
{
SimulationList.AddItem(pair.Key);
IDToPath.Add(id, pair.Value);
id++;
}
}
private void SimulationSelected(int index)
{
string path = IDToPath[index];
SimSelector.GoToScene(path);
}
}
}
goodymind | 2022-11-25 06:06