OnLoadEventCompleted being called two times

I dont know how and why but OnLoadEventCompleted is being called twice as per console logs

I see console prints, It is repeating the debugs twice

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

    if (IsServer){
        NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnect;
        NetworkManager.Singleton.SceneManager.OnLoadEventCompleted += AllPlayersJoinedLoaded;
    }
}
void AllPlayersJoinedLoaded (
    string sceneName,
    UnityEngine.SceneManagement.LoadSceneMode loadSceneMode,
    List<ulong> clientsCompleted,
    List<ulong> clientsTimedOut
)
{
    if(IsServer)
    {
        UnityEngine.Debug.Log("All players joined loaded");
        foreach( ulong clientId in NetworkManager.Singleton.ConnectedClientsIds )
        {
            Transform playerTransform = Instantiate(playerPrefab);
            UnityEngine.Debug.Log("Spawned player for client id " + clientId);
            playerTransform.GetComponent<NetworkObject>().SpawnAsPlayerObject(clientId, true);
        }
        UnityEngine.Debug.Log("game state value changed by client id " + OwnerClientId);
        gameState.Value = GameState.OnCountDownToStart;
    }
}

This is my code from GameManager Script which is attached to a network gameobject which is only in Game Scene. At intial scene, all clients (players) are in Lobby scene then when all are ready- they move to game scene and Load Game Scene using Load Scene function by NetworkManager- making sure Server, Host, Client all are in same scene
After all clients are loaded in the game scene, i want to check it and spawn player prefabs

Case 1:

When I build 2 Unity applications in Windows and I also Play a game in Unity editor mode as 3rd- I create a lobby in editor mode and the 2 build application join by code. Everything works perfectly and 1 player prefab for each client id which is spawned as NetworkPlayerObject
BUT

Case 2:

When I build 2 applications. Create a lobby in 1 application and then join it with code from another lobby. Player prefab is spawned two times for EACH CLIENT ID

CASE 3:

I build application for MacOS from my macbook and then build application for Windows from Windows obviously. Then i run both build application.
PART A: WHEN MAC CREATE LOBBY, windows join by code- NO bug. No issues. ANd there is only 1 player prefab for each client

BUT

PART B: WHEN WINDOWS CREATE LOBBY- and mac app join by code. There is 2 Player prefab for each client. Twice spawning again

ALL OF THESE ABOVE CASES CAN BE SEEN IN CONSOLE WITH DEBUG.LOG

I hope this information is enough. I really need help- stuck with this error for long enough, read most post and docs.

I have a few questions that might help me better understand where the issue could be.

  • Server, Host, Client all are in same scene
    • You should only have either a server or host, which of the two do you have?
  • When you load your scene, do you load it additively or in single mode?
    • If you load in single mode:
      • Does the lobby and the scene you load into both have a GameManager or does the lobby have the only instance that is marked as DontDestroyWithScene so it persists between the scene transition?
        • I ask this because if you have one in each scene (lobby and then the scene you load into) you would get that kind of behavior.
      • If there is only one GameManager and it persists between the lobby and scene loaded, it looks like you don’t unsubscribe from the OnLoadEventCompleted event once all players have loaded the lobby scene and have players spawned. When you load into the game scene that will get invoked again (i.e. all clients finished loading) and you would get duplicate log messages and players spawned.

If the very last thing I mention is the case, I would just unsubscribe from the OnLoadEventCompleted once you are finished processing the event:


void AllPlayersJoinedLoaded (
    string sceneName,
    UnityEngine.SceneManagement.LoadSceneMode loadSceneMode,
    List<ulong> clientsCompleted,
    List<ulong> clientsTimedOut
)
{
    if(IsServer)
    {
        UnityEngine.Debug.Log("All players joined loaded");
        foreach( ulong clientId in NetworkManager.Singleton.ConnectedClientsIds )
        {
            Transform playerTransform = Instantiate(playerPrefab);
            UnityEngine.Debug.Log("Spawned player for client id " + clientId);
            playerTransform.GetComponent<NetworkObject>().SpawnAsPlayerObject(clientId, true);
        }
        UnityEngine.Debug.Log("game state value changed by client id " + OwnerClientId);
        gameState.Value = GameState.OnCountDownToStart;
        NetworkManager.Singleton.SceneManager.OnLoadEventCompleted -= AllPlayersJoinedLoaded;
    }
}