Help adapting my additive Scene Management system to VR Multiplayer Template

Hello there!

I’d like to ear some feedback to better learn what is the right approach to implement what I want to do.
I’ve been working on a XR application for Meta Quest 3 that let the user visit some virtual environments. Recently, I was asked to implement multi-user features in this prototype, so I migrated my project into a new one having VR Multiplayer Template as a base.

The app flow is currently managed by a custom SceneManager I wrote that handles additive scene loading. There is one bootstrap startup scene with mostly permanent GameObjects (and DDoL ones), including this custom SceneManager and the XR Origin. At start the SceneManager loads the first scene additively, which is an AR scene selector menu for the user to choose the environment he wants to visit. When the user enter an environment, the SceneManager unloads the AR scene menu and loads the chosen environment. Same (reversed) when the user exits it.

public class MySceneManager : MonoBehaviourSingleton<MySceneManager>
{
    [SerializeField] private string firstSceneToLoad;
    [SerializeField] private FadeController fadeController;
    [SerializeField] private float fadeDuration;

    private int _currentSceneLoaded;

    public override void Awake()
    {
        base.Awake();

        fadeController.SetAlpha(0);
        LoadScene(firstSceneToLoad, false);
    }

    public void LoadScene(string sceneName, bool fade = true)
    {
        StartCoroutine(LoadSceneCoroutine(sceneName, fade));
    }

    private IEnumerator LoadSceneCoroutine(string newScene, bool fade)
    {
        if(fade)
        {
           yield return fadeController.FadeCoroutine(fadeDuration, FadeController.Direction.Out);
        }

        if (_currentSceneLoaded != 0)
        {
            yield return SceneManager.UnloadSceneAsync(_currentSceneLoaded);
            Debug.Log($"[{GetType().Name}] Scene {_currentSceneLoaded} unloaded");
        }

        yield return SceneManager.LoadSceneAsync(newScene, LoadSceneMode.Additive);
        Debug.Log($"[{GetType().Name}] Scene {newScene} loaded");
        var scene = SceneManager.GetSceneByName(newScene);
        _currentSceneLoaded = scene.buildIndex;
        SceneManager.SetActiveScene(scene);

        if (fade)
        {
            yield return fadeController.FadeCoroutine(fadeDuration, FadeController.Direction.In);
        }
    }
}

Now it comes the multiplayer part. I want that each user can be able to start a new lobby as well as joining one in any time, regardless of what scene has loaded locally. A client who joins a lobby should log in the same scene of the host. If the host leaves the current scene, the lobby gets closed and all clients should be disconnected. If a client leaves the current scene, he gets disconnected by the lobby.

How should I rethink my scene management system? I was trying to refactor my SceneManager in order to use NetworkSceneManager, but NetworkSceneManager is not available until a network session is actually instantiated (so when the host starts a lobby), so I can’t handle scene management when offline.
Is there a way to achieve this result using already provided NGO Scene Management? Or do I need to create a custom system?

Any feedback or help is appreciated! Thanks!

Hey there, thanks for checking out the VR Multiplayer Template!

TL;DR you will most likely need to create a custom scene manager that handles both setting the active multiplayer scene (when online), and the non multiplayer scenes (when offline).

I recently wired up networked scene switching in a personal project. The main thing is to make sure of is that the proper items are marked as DDoL (which it sounds like you are doing for some objects, but maybe not all?).

I would definitely recommended using the NetworkSceneManager since it will auto sync the active scene determined by the host of the room. Because this process is automatic, you just need the host to set that active scene, then when new clients join they will automatically load into the hosts scene.

You can have your scene manager work when not online by having specific loading functions when offline vs online, and choose whichever one you want respectively. That is at least how I’m doing it in my personal project.