Search Unity

Resolved NetworkManager disposing NetworkSceneManager on Shutdown, causing scene loading to break

Discussion in 'Netcode for GameObjects' started by alexennerfelt, Mar 2, 2023.

  1. alexennerfelt

    alexennerfelt

    Joined:
    Jan 7, 2017
    Posts:
    15
    Edit: Resolved! This was all caused by me caching the
    NetworkSceneManager
    , got resolved when just switching to using
    NetworkManager.Singleton.SceneManager

    Learn from my mistakes everyone :)

    My case:

    1. Start Host by calling
      NetworkManager.StartHost()
    2. Load a Scene using
      NetworkManager.SceneManager.LoadScene()
    3. Then unloading the scene calling NetworkManager.SceneManager.UnloadScene()
    4. Then shut down the host calling NetworkManager.Shutdown()
    5. Then Host another game again and load a scene using the same steps

    Here where I run into an issue:
    When calling
    [I]NetworkManager.Shutdown()[/I] 
    it calls NetworkSceneManager.Dispose()

    This sets SceneEventDataStore to null and then never initializes it again.

    Code (CSharp):
    1. /// <summary>
    2.         /// Handle NetworkSeneManager clean up
    3.         /// </summary>
    4.         public void Dispose()
    5.         {
    6.             SceneUnloadEventHandler.Shutdown();
    7.  
    8.             foreach (var keypair in SceneEventDataStore)
    9.             {
    10.                 if (NetworkLog.CurrentLogLevel <= LogLevel.Normal)
    11.                 {
    12.                     NetworkLog.LogInfo($"{nameof(SceneEventDataStore)} is disposing {nameof(SceneEventData.SceneEventId)} '{keypair.Key}'.");
    13.                 }
    14.                 keypair.Value.Dispose();
    15.             }
    16.             SceneEventDataStore.Clear();
    17.             SceneEventDataStore = null;
    18.         }
    This causes a NRE when using NetworkSceneManager.LoadScene() because it needs to access it in the BeginSceneEvent()

    Code (CSharp):
    1.   /// <summary>
    2.         /// Creates a new SceneEventData object for a new scene event
    3.         /// </summary>
    4.         /// <returns>SceneEventData instance</returns>
    5.         internal SceneEventData BeginSceneEvent()
    6.         {
    7.             var sceneEventData = new SceneEventData(m_NetworkManager);
    8.             SceneEventDataStore.Add(sceneEventData.SceneEventId, sceneEventData);
    9.             return sceneEventData;
    10.         }
    This completely breaks the possibility of leaving a game and then hosting a new game.

    Is there a good way to fix this, am I using it wrong. Is this a known issue that has any fixes on the horizon?
     
    Last edited: Mar 2, 2023
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,005
    Do you have a startup scene, or do you go straight to the scene where you call StartHost?
    It's best to have a startup scene that contains the NetworkManager, then switch to an actual scene that might normally be the "menu" and from there, call StartHost and then load the scene you want to load. That way things are cleanly separated. Not sure what would happen if you try to UnloadScene the scene that the app starts in. Just in case that's what your setup is.
     
  3. alexennerfelt

    alexennerfelt

    Joined:
    Jan 7, 2017
    Posts:
    15
    I resolved the issue and edited the post :) Thank you for the advice though and I have it set up with a Bootstrap scene that loads all my systems that will be persistent throughout the application lifecycle.