0 votes

This is probably something regarding C#, but i'm not figuring out why. It's my first time dealing with Tasks so I have no clue what's wrong at all.

I'm currently working on a SceneManager class to load scenes, and the loading works fine, but I want it to work asynchronously and I don't get why it's hanging on the main thread (during loading it freezes, Not responding, as if it weren't sync).

Here's my code:

This is the loading method, loads properly.

private async Task ChangeScene(string path, SceneTree tree)
{
    ResourceInteractiveLoader ril = ResourceLoader.LoadInteractive(path);

    while (true)
    {
        Error err = ril.Poll();
        if (err == Error.FileEof)
        {
            Resource res = ril.GetResource();
            GD.Print("Loading done");
            break;
        }
        if (err == Error.Ok)
        {
            float progress = (float)ril.GetStage() / (float)ril.GetStageCount();
            GD.Print(progress);
        }

        await (ToSignal(tree, "idle_frame"));
    }
}

This is the function in the same script that runs the task.

    public static async void LoadScene(string path, SceneTree tree)
{
    await Task.Run(async () =>
    {
        await SceneManager.Instance.ChangeScene(path, tree);
    });
}

My SceneManager.cs is a C# singleton class that inherits node (to call ToSignal()), and I call my LoadScene call on my Global.cs ChangeScene function:

    public static void ChangeScene(string path)
{
    SceneManager.LoadScene(path, tree);
}

Finally the ChangeScene call is linked to a Signal when pressing a button:

public void OnStartGamePressed()
{
    Global.ChangeScene("res://Assets/Scenes/game.tscn");
}

I have no idea what's wrong, any tips?

Godot version 3.4.2
in Engine by (39 points)

1 Answer

+1 vote
Best answer

Task.Run should execute the code on another thread, since you are doing this you shouldn't use the "await ToSignal". Just let it block until is finished. Although I'm not sure if you really need the Resource Interactive Loader since you are offloading the task to another thread.

The method described here is to load on the main thread (that's why the code is inside de _process method), the difference is that using this method you won't just wait until the resource is fully loaded, you can do things step by step.

by (243 points)
selected by
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.