Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

NetworkMananager.ServerChangeScene fails to spawn client's player prefab ~50% of the time

Discussion in 'Multiplayer' started by deliinteractive, Jun 14, 2016.

  1. deliinteractive

    deliinteractive

    Joined:
    Oct 8, 2014
    Posts:
    25
    Howdy again!

    I recently tried to tie together a scene where our players pick their equipment and a scene where they actually do the playing. Once they've picked their equipment, they hit a confirm button and the server runs NetworkManager.ServerChangeScene. This is using the default implementation of the NetworkManager component, and a player object which is NOT set to DontDestroyOnLoad.

    When each player changes scene in response to that NetworkManager call, roughly 50% will fail to spawn their player object, even with "Auto Create Player" checked in the NetworkManager's inspector properties. For the remainder that DO spawn their player, the host does not display them or their input correctly. On the host's screen, client players which DID spawn didn't appear to run some of their Start() functions entirely, as the players accommodate scene changes by pulling their appearance and equipment settings from static variables, then sending the content of those variables out by commands and subsequent ClientRpcs. Some of the networking code on client players appears to run on the host end (the SyncAnimator and SyncTransform components are working fine), but any custom code (including one which sets the player to duck or one which sets the player to flip their x-scale) does not run from the host version of a client's player. And again, that's when the client player even shows up.

    Once again, my team and I are just not sure where to start looking with this. We are very seriously considering combining the majority of menus and the main game scene into a single scene and simply never changing out of it due to the instability we're finding. Does anyone know what might be going wrong here?
     
    PhilippG likes this.
  2. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    I have the same problem or a problem that results in the same behavior:
    When I try to change the scene there is a 50/50 chance player objects get spawned for clients.
    At least I have an error message from the log:

    There is already a player at that playerControllerId for this connections.
    UnityEngine.Networking.NetworkManager:OnServerAddPlayer(NetworkConnection, Int16)

    This is thrown in NetworkManager.OnServerAddPlayerInternal in this section:
    Code (CSharp):
    1. if (playerControllerId<conn.playerControllers.Count  && conn.playerControllers[playerControllerId].IsValid && conn.playerControllers[playerControllerId].gameObject != null)
    2. {
    3.     if (LogFilter.logError) { Debug.LogError("There is already a player at that playerControllerId for this connections."); }
    4.     return;
    5. }
    So it seems theres already a playerGO instantiated for this connection.

    I am currently testing on a single machine with multiple instances, so maybe that is the problem. I can imagine the connection comparison does not work when having the same networkadress in multiple clients.

    I will test on multiple machines now. Hopefully that will do.

    Edit: After testing, I get the feeling its more a performance problem. I had the issue when I was working on my laptop. Running two instances has it dropping fps a lot. I did now first try connecting the laptop and with a desktop pc and that worked fine. The I moved over to the more powerful desktop machine and tried running 4 instances at once. That still does work fine. So probably its a timing issue? The cleanup might not have been finished when OnServerAddPlayerInternal is called. If I'm right thats bad. What to do?
     
    Last edited: Jun 19, 2016
  3. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    Ok so I was just looking into this again, and I figured that for me the problem did only occur when the client did already load the new scene while the server was still in the previous one. This happened whenever I called ServerChangeScene from the client (via Cmd though, weird).
    So now it seems just fine when I do this:
    Code (CSharp):
    1. public override void ServerChangeScene(string newSceneName)
    2. {
    3.     SceneManager.LoadScene(newSceneName);
    4.     base.ServerChangeScene(newSceneName);
    5. }
    6.  
    So I do load the new scene synchronous first giving the server time to boot up the new level, and call ServerChangeScene afterwards. The loading time is of course uch longer now on the client but at least it seems reliable now...
     
  4. Captain_Flaush

    Captain_Flaush

    Joined:
    Apr 20, 2017
    Posts:
    65
    Hello,
    I've bumped into this issue as well. Your solution generates other issues for me. the player's network transform generate errors for a while. Maybe they get loaded first on the client and then the server starts getting messages from them.
    Isn't there a better way to sync scene loading between clients and server?
     
  5. BlueStarGeneral

    BlueStarGeneral

    Joined:
    Jan 19, 2018
    Posts:
    4
    Thanks to PhillipG!

    I can confirm that works, here's the code I use.

    if (netman != null)
    if (Globals.net_type_host == 0) // Is the server...
    {
    // netman.ServerChangeScene("offlineScene");
    SceneManager.LoadScene("offlineScene");
    netman.ServerChangeScene("offlineScene");
    }

    Just calling ServerChangeScene nevers spawns the clients,
    (I've only tested it on Lan so if it doesn't work on internet I'll update this post)

    PSD
     
  6. Driiades

    Driiades

    Joined:
    Oct 27, 2015
    Posts:
    151
    The problem with the HLAPI is that it use a reliable channel, and not a reliable ORDERED channel for channel 0.

    So you can have the SpawnPlayer and ServerChangeScene message in Unordered sequence.

    You can imagine the problem if you expect the player to spawn after the server change scene.

    The best way is to change the default channel 0 by an ordered channel. This solve 90% of HLAPI bug in fact.
     
  7. BrunoPuccio

    BrunoPuccio

    Joined:
    Dec 13, 2017
    Posts:
    22
    are there any cons of changing the default channel? and how do you do it?
     
  8. Driiades

    Driiades

    Joined:
    Oct 27, 2015
    Posts:
    151
    A con ? no, maybe it's slower because you use a reliable ordered channel, but..meh it resolve bug and your app can run ...so ... ^^

    You have to modify the networkManager (which had a first reliable channel and a second unreliable channel by default).

    An other things is that all your NetworkBehaviour will use the channel 0, which is ordered now, so maybe slower to be receive, but you can modify it with the attributes.
     
  9. Nodragem

    Nodragem

    Joined:
    May 20, 2017
    Posts:
    5
    It seems that Reliable Sequenced is already the default for channel #0.