Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Feedback NetworkManager should have a OnShutdown event

Discussion in 'Netcode for GameObjects' started by CodeSmile, Oct 10, 2022.

  1. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    2,486
    NetworkManager has no built-in event that occurs on shutdown.

    I added a disconnect button for clients and within the GUI I just call NetworkManager.Singleton.Shutdown(). It works, but ... other systems don't get to know about that. For instance, I may want to load a scene on disconnect in a different subsystem.

    Since OnClientDisconnected isn't called in that case (due to the client logically disconnecting itself) I currently have no other option than to create my own event delegate to forward the disconnect/shutdown request by user action. Not much extra work but really something NetworkManager should already provide ie an OnShutdown event.
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    2,486
    Found a workaround that works in my case.

    In the Scene loading NetworkBehaviour I added an Update() method that checks if we are a client (non-host) but not connected:

    Code (CSharp):
    1.         private void Update()
    2.         {
    3.             if (IsClient && IsServer == false && NetworkManager.IsConnectedClient == false)
    4.             {
    5.                 LoadSceneNonNetworked();
    6.             }
    7.         }
    This works for me because IsClient is set to false when NetworkManager.Shutdown() ran, and it's also false before joining.
     
    pradotech likes this.
  3. pradotech

    pradotech

    Joined:
    Oct 17, 2019
    Posts:
    35
    Nice workaround, I just adapted to a Coroutine like this:
    Code (CSharp):
    1.     private IEnumerator LoadMenuDelayed()
    2.     {
    3.         while (NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsConnectedClient)
    4.             yield return null;
    5.  
    6.         SceneCore.Instance.LoadMainMenu();
    7.     }
     
    CodeSmile likes this.
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    2,486
    DRY principle applied:
    Code (CSharp):
    1.     private IEnumerator LoadMenuDelayed()
    2.     {
    3.         var netMan = NetworkManager.Singleton;
    4.         while (netMan.IsClient || netMan.IsServer || netMan.IsConnectedClient)
    5.             yield return null;
    6.         SceneCore.Instance.LoadMainMenu();
    7.     }
     
  5. Lasko1

    Lasko1

    Joined:
    Dec 30, 2021
    Posts:
    5
    Found this thread because of the exact same problem I'm having.

    To avoid performing a check every frame, I created a new "ExtendedNetworkManager" class that inherits from NetworkManager:

    Code (CSharp):
    1. public class ExtendedNetworkManager : NetworkManager
    2. {
    3.     public static event EventHandler OnShutdown;
    4.  
    5.     public static void NotifiedShutdown(object sender)
    6.     {
    7.         Singleton.Shutdown();
    8.         OnShutdown?.Invoke(sender, EventArgs.Empty);
    9.     }
    10. }
    I replaced the NetworkManager component on my NetworkManager GameObject with the new ExtendedNetworkManager component.

    Then, instead of calling NetworkManager.Singleton.Shutdown(), I use ExtendedNetworkManager.NotifiedShutdown(this). Observers subscribe to ExtendedNetworkManager.OnShutdown.

    I would love a native OnShutdown event though.
     
    Last edited: Nov 2, 2022