How to set a loading screen with C#?

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

In a game I’m developing with C# in Godot 3.2.3, I have a main menu, where I have a button that should start a new game. Now, my game is based on maps, which have a lot of resources like units, tilemaps, and more. I guess that by that last fact, when I start a game, the game window freezes for a while saying that is not responding, until the map loads. According to me, this happens 'cause the game is loading the scene.

Based on this idea, I read the Godot Docs, specially this one: Background loading — Godot Engine (stable) documentation in English Unfortunately, this one was written in GDScript, so I couldn’t follow it the same way, but I tried to make a C# approach, that lead me to the code at the bottom. However, this did not behaved as I expected. I discovered that the code that avoids my map to load is the currentScene.QueueFree(). Without this one, the map loads, but the code is useless, since again the game freezes with the “no responding” warning and with currentScene.QueueFree(), my map is never going to load.

Does anyone knows something about the matter? Any experience? I thank in advance your support.

StartMenu.cs:

using Godot;
using System;

public class StartMenu : CanvasLayer
{
    public ResourceInteractiveLoader loader = null;
    float maxTime = 150;
    int waitFrames = 0;
    float progress = 0;
    Node currentScene;

    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        var root = GetTree().Root;
        currentScene = root.GetChild(root.GetChildCount() - 1);
    }

    public void _on_StartButton_pressed()
    {
        loader = ResourceLoader.LoadInteractive("res://scenes/PlayMap.tscn");
        if (loader == null)
        {
            GD.Print("Scene Error");
            return;
        }
        SetProcess(true);
        currentScene.QueueFree();

        var loading = GetNode<AnimatedSprite>("Loading");
        loading.Animation = "loading";
        loading.Play();

        waitFrames = 1;

    }

    public void UpdateProgress()
    {
        progress++;
        GD.Print(progress);
    }

    public void SetNewScene(Resource sceneResource)
    {
        var newScene = sceneResource as PackedScene;
        currentScene = newScene.Instance();
        GetTree().Root.AddChild(currentScene);
    }

    // Called every frame. 'delta' is the elapsed time since the previous frame.
    public override void _Process(float delta)
    {
        if (loader == null)
        {
            SetProcess(false);
            return;
        }

        if (waitFrames > 0)
        {
            waitFrames -= 1;
            return;
        }

        var t = OS.GetTicksMsec();

        while (OS.GetTicksMsec() < t + maxTime)
        {
            var err = loader.Poll();
            if (err == Error.FileEof)
            {
                var resource = loader.GetResource();
                loader = null;
                SetNewScene(resource);
                break;
            }
            if (err == Error.Ok)
            {
                UpdateProgress();
            }
            if (err != Error.Ok && err != Error.FileEof)
            {
                GD.Print(err);
                loader = null;
                break;
            }
        }
    }
}

Has this been solved?

goodymind | 2022-11-25 12:44