How do I properly reload a Unity Scene that uses MRTK for the Hololens2?

1.9k Views Asked by At

This is my first project using the Hololens and MRTK for Unity. I want to make a button that restarts the experience for the player when pushed.

I connected a button to a new script with the following code:

SceneManager.LoadScene(SceneManager.GetActiveScene().name);

When the button is pushed the scene seems to reload, but all MRTK/Hololens functionality stops. The hand and eye-tracking are unresponsive, and I am unable to interact with holograms.

I know I can manually make a reset method that moves all the objects in the scene and resets specific scripts, but I'm trying to completely unload and reload as much of the Unity application as possible from a push of a button.

So, how do I properly reload a Unity Scene on the Hololens2? I'm still doing research on this and will update what I find here. I greatly appreciate any assistance here, Thank you!

2

There are 2 best solutions below

1
On BEST ANSWER

MRTK actually has a scene system that neatly wraps loading/unloading scenes as well as optional concepts like lighting.

Take a look at the docs/guides here: https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/SceneSystem/SceneSystemGettingStarted.html

1
On

Always avoided it for exactly these kind of issues with MRTK.


I would rather suggest:

Have one MRTK and landing scene at build index 0. This one you never un- or reload. Here you also place your manager script responsible for (re)loading the content.

And load everything else via additive scene loading and then later unload and reload only these additional scenes.

This leaves the MRTK intact and you can still load, unload and reload your app content.


The mentioned manager class might look somewhat like

// Put this into the MRTK scene
public class SceneLoader : MonoBehaviour
{
    private void Awake ()
    {
        // Register callback for everytime a new scene is loaded
        SceneManager.sceneLoaded += OnSceneLoaded;

        // Initially load the second scene additive
        SceneManager.LoadScene(1, LoadSceneMode.Additive);
    }

    // Called when a new scene was loaded
    private void OnSceneLoaded(Scene scene, LoadSceneMode loadMode) 
    {
        if(loadMode == LoadSceneMode.Additive)
        {
            // Set the additive loaded scene as active
            // So new instantiated stuff goes here
            // And so we know which scene to unload later
            SceneManager.SetActiveScene(scene);
        }
    }
        

    public static void ReloadScene()
    {
        var currentScene = SceneManager.GetActiveScene();
        var index = currentScene.buildIndex;

        SceneManager.UnloadScene(currentScene);

        SceneManager.LoadScene(index, LoadSceneMode.Additive);
    }

    public static void LoadScene(string name)
    {
        var currentScene = SceneManager.GetActiveScene();

        SceneManager.UnloadScene(currentScene);

        SceneManager.LoadScene(name, LoadSceneMode.Additive);
    }

    public static void LoadScene(int index)
    {
        var currentScene = SceneManager.GetActiveScene();

        SceneManager.UnloadScene(currentScene);

        SceneManager.LoadScene(index, LoadSceneMode.Additive);
    }
}

And then for reloading your current scene do

SceneLoader.ReloadScene();

or as usual load a different scene via

SceneLoader.LoadScene("SceneName");

or

SceneLoader.LoadScene(buildIndex);

Of course you could also implement the async versions following the API examples.