Help Needed: Detecting Host Disconnection in Unity Netcode

Hi everyone,

I’m working on a multiplayer game using Unity Netcode for GameObjects, and I’ve encountered an issue with detecting the host’s disconnection.

I have a HostDisconnectionManager script attached to an empty GameObject in the scene. Its purpose is to listen for disconnections using the NetworkManager.Singleton.OnClientDisconnectCallback() event.

I also have a HostDisconnectUI script attached to my player’s prefab, which handles showing a UI element when the host disconnects.

My goal is for the HostDisconnectionManager to notify the HostDisconnectUI on all clients to execute the HostDisconnected() method when the host disconnects.

The Issue: When the host disconnects, the NetworkManager.Singleton.OnClientDisconnectCallback() event is triggered as expected. However, the clientId it provides corresponds to the ClientOwnerId of the remaining clients instead of the ServerClientId (which should be 0 for the host). This causes the logic to fail, as the script cannot correctly identify the host disconnection.

Here are the scripts:

using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;

public class HostDisconnectionManager : MonoBehaviour
{
    void Start()
    {

        NetworkManager.Singleton.OnClientDisconnectCallback += NetworkManager_OnClientDisconnectCallback;

    }

    void Update()
    {
        
    }


    void NetworkManager_OnClientDisconnectCallback(ulong clientId)
    {
        Debug.Log("Host Disconnected: " + clientId);

        if ( clientId == NetworkManager.ServerClientId)
        {
            Debug.Log("Host has disconnected!");
            HostDisconnectUI[] ui = FindObjectsOfType<HostDisconnectUI>();
            foreach (HostDisconnectUI ui2 in ui)
            {
                ui2.HostDisconnected();
            }
        }
    }

}

using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;

public class HostDisconnectUI : MonoBehaviour
{


    public GameObject hostHasDisconnectedTemplate;
    public UnityEngine.UI.Button goToMainMenuButton;

    void Start()
    {
        Hide();
    }


    public void HostDisconnected()
    {
        hostHasDisconnectedTemplate.SetActive(true);
    }

    void Hide()
    {
        hostHasDisconnectedTemplate.SetActive(false);

    }

}

How can I reliably detect the host’s disconnection and notify all player instances to display the host disconnection UI? Any help or insight would be very helpful!

Thank you for your time!

By ignoring the host. If the host leaves, the session ends for everyone, thus all clients get disconnected and OnClientDisconnectCallback runs for the local client. As does OnClientStopped.

You don’t need any specific “Host left” UI anyway. It suffices to tell the player “Session ended” because whether the host left, or the client’s network dropped, or NetworkManager received OnTransportFailure (must implement!!) shouldn’t concern your game. The session ended, that’s all there is to it.

If the client disconnects purposefully through the game’s UI you just set a flag and check it. If set, you don’t display anything in that case and reset the flag if you really want to avoid showing that “Session ended” message.

Thank you for your response! I actually took CodeMonkey’s multiplayer game course on YouTube (Link), and in the timestamp 3:18:8, he implemented this functionality using the same code I provided. However, in my case, it doesn’t seem to work as expected.

Could there be differences in the setup or nuances in how the callback operates that might explain this discrepancy? I’d love to hear your thoughts!

Hi @tejassinghchauhan ,

Here is the documentation source.
You can listen “NetworkManager.OnServerStopped” instead of OnClientDisconnectCallback event for this case.

Thank you for your response!

I tried to implement the functionality using the code below. However, the OnServerStopped event only seems to run on the host’s device, not on the clients.

using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;

public class HostDisconnectionManager : MonoBehaviour
{
    void Start()
    {

        NetworkManager.Singleton.OnServerStopped += OnServerStopped;
    }

    private void OnDestroy()
    {
        if (NetworkManager.Singleton != null)
        {
            NetworkManager.Singleton.OnServerStopped -= OnServerStopped;
        }
    }

    void Update()
    {
        
    }


    private void OnServerStopped(bool isShutdown)
    {
        if (!NetworkManager.Singleton.IsClient)
        {
            return;
        }

        ShowHostDisconnectedUI();
        Debug.Log("Server stopped");
    }

    private void ShowHostDisconnectedUI()
    {
        HostDisconnectUI[] ui = FindObjectsOfType<HostDisconnectUI>();
        foreach (HostDisconnectUI ui2 in ui)
        {
            ui2.HostDisconnected();
        }
    }

}

The issue is that this logic is not triggering on the client devices when the host disconnects. but it only works on the host’s device. Could you please help me understand what I might be missing or if there’s a better way to achieve this functionality?

I shared the documentation because you can choose any events for your case.

For your situation you can also listen “NetworkManager.OnClientStopped” event.But it is also triggered when the client voluntarily leaves the server. You can hold a variable when client left the room voluntarily than you can check this variable when “NetworkManager.OnClientStopped” is triggered.