This document is about: FUSION 2
SWITCH TO

Scene Loading

Overview

Fusion internally contains no Unity Scene handling implementations, but it does provide an INetworkSceneManager interface, where you can define how Fusion responds to various Scene related events - such as scene changes. An implementation of INetworkSceneManager hereon will be referred to as a Scene Manager.

An implementation of INetworkSceneManager needs to be assigned in the NetworkRunner.StartGame() method via the StartGameArgs.SceneManager field. If no implementation is provided (null), Fusion will create an instance of the NetworkSceneManagerDummy class and log an error communicating that it will not be able to link scene objects.

An default implementation named NetworkSceneManagerDefault comes with Fusion which can:

  • Load and Unload scenes.
  • Supports regular scene loading and scene loading via addressables.
  • Can reload currently active scenes.
  • Loads up to 8 scenes simultaneously using additive scene loading.
  • Supports multi-peer scene loading with correct PhysicsScene associations for each Runner.

Load and Unload scenes

Important: Both LoadScene() and UnloadScene() are only allowed to be called on the Server/Host or Master Client. (This is enforced by the default scene manager implementation. Custom implementations must also enforce this)

To load a scene, simply call NetworkRunner.LoadScene() passing the SceneRef of the scene and the LoadSceneParameters. Keep in mind that loading with single load mode will unload all previous scenes, while with additive scene loading previous scenes remain loaded.

C#

// Loading 3 scenes in additive mode.
if (Runner.IsSceneAuthority) {
  Runner.LoadScene(SceneRef.FromIndex(1), LoadSceneMode.Additive);
  Runner.LoadScene(SceneRef.FromIndex(2), LoadSceneMode.Additive);
  Runner.LoadScene(SceneRef.FromIndex(3), LoadSceneMode.Additive);
}

The index used to create the SceneRef is the index of the scene in the Unity build. To get the index of the current scene you can use SceneManager.GetActiveScene().buildIndex. For other scenes the index can be found by scene path using SceneUtility.GetBuildIndexByScenePath. For instance to load the Scene that is stored at Assets/Scenes/GameScene.unity the following code is used:

C#

  Runner.LoadScene(SceneRef.FromIndex(SceneUtility.GetBuildIndexByScenePath("Assets/Scenes/GameScene.unity")), LoadSceneMode.Additive);

To unload a scene, simply call NetworkRunner.UnloadScene() passing the SceneRef of the scene to be unloaded.

C#

// Unloading scene 1.
if (Runner.IsSceneAuthority) {
  Runner.UnloadScene(SceneRef.FromIndex(1));
}

It is also possible to reload scenes by unloading and loading them again in sequence. The NetworkSceneManagerDefault implementation maintain a Version field that works as a counter, increasing every time a scene is loaded or unloaded, this value is used to register the load ID of the scene object to differentiate between the last loaded scene and the new loaded one, even though they're the same scene.

C#

// Reloading scene 2.
if (Runner.IsSceneAuthority) {
  Runner.UnloadScene(SceneRef.FromIndex(2));
  Runner.LoadScene(SceneRef.FromIndex(2), LoadSceneMode.Additive);
}

SceneRefs can be created from a scene index with SceneRef.FromIndex(int index) or from a path, mostly used to create references to addressables scenes, with SceneRef.FromPath(string path).

Creating a custom Network Manager

INetworkSceneInfo

Represents user-controlled active scene information. This interface should be implemented by an unmanaged type, and it is what the NetworkRunner will network in order to properly sync scene loading. Whenever the scene authority (Host/Server or Master Client) changes the scene info, OnSceneInfoChanged() will be called on the INetworkSceneManager instance registered on the NetworkRunner.

NetworkSceneInfoDefault

The default implementation of INetworkSceneInfo. Can store up to 8 active scenes and allows for duplicates. It is a great starting point to creating a custom implementation.

INetworkSceneManager

Provide a custom implementation of this interface on StartGameArgs to have full control on how scene loading is handled. Keep in mind that this implementation needs to call the Fusion scene loading callbacks Runner.InvokeSceneLoadStart(sceneRef) and Runner.InvokeSceneLoadDone(SceneLoadDoneArgs). Take a look at the NetworkSceneManagerDefault implementation to see the default behaviour.

When implementing a custom scene manager, the interface will provide the following:

  • void Initialize(NetworkRunner runner) : Called when the runner initializes itself. Use it to store the NetworkRunner reference and do any warmup necessary.

  • void Shutdown() : Called when the runner shutdown. Use it to release any references and stop any pending actions.

  • bool IsBusy : Use this property to tell when the scene manager is busy loading a scene or doing anything else that the NetworkRunner or other systems on your game may need to be aware of.

  • Scene MainRunnerScene : Use this property to tell which scene is the main scene of a NetworkRunner. This is mainly used for multi-peer support. (Check the default implementation for more information)

  • bool TryGetPhysicsScene2D(out PhysicsScene2D scene2D) : Set the 2D physics scene on the out parameter, return the result of the operation.

  • bool TryGetPhysicsScene3D(out PhysicsScene scene3D) : Set the 3D physics scene on the out parameter, return the result of the operation.

  • void MakeDontDestroyOnLoad(GameObject obj) : Make an object not be destroyed on load. Used for multi-peer support. (Check the default implementation for more information)

  • void MoveToRunnerScene(GameObject obj) : Move the passed object to the scene related with the NetworkRunner. This is only used for multi-peer support. (Check the default implementation for more information)

  • bool IsRunnerScene(Scene scene) : Return if this scene is related with the NetworkRunner. Used for multi-peer support. (Check the default implementation for more information)

  • NetworkSceneAsyncOp LoadScene(SceneRef sceneRef, LoadSceneParameters parameters) : Use this method to load a new scene with the received parameters. The way that the scene will be loaded is entirely up to the developer, the only needed step is to register the newly loaded NetworkObjects with NetworkRunner.RegisterSceneObjects(SceneRef scene, NetworkObject[] objects, byte loadId = 0). The additional loadId parameter is passed to ensure each scene load yields unique type ids for scene objects.

  • NetworkSceneAsyncOp UnloadScene(SceneRef sceneRef) : Use this method to unload a scene.

  • void OnSceneInfoChanged() : Called when the INetworkSceneInfo on the NetworRunner is changed. Use this method to react and trigger scene loading on clients since only the scene authority should be able to call LoadScene.

  • SceneRef GetSceneRef(string sceneName) : Use this method to return a SceneRef based on the provided scene name.

Back to top