Search Unity

How can a client change their scene when joining mid game?

Discussion in 'Netcode for GameObjects' started by cado82, Jun 1, 2022.

  1. cado82

    cado82

    Joined:
    Jul 29, 2020
    Posts:
    25
    I have two scenes, let's call them StartGameScene and GameScene. StartGameScene has 2 buttons, one to Start a host and one to join a game (using a join code).

    If I spin up an instance of the game and click to Start a host, the NetworkSceneManager is called to switch the host to the GameScene. This works fine and my player prefab is spawned correctly along with any network objects that I've spawned.

    If I then use a different instance of the game to join the in progress game using the join code, how can I have that client switch to the GameScene?

    I tried calling NetworkSceneManager using the client but I'm met with an error that only the server can use that (I understand why). If I use the regular SceneManager to switch to the GameScene on the client, I don't have any of the network objects spawned and it's as if I just loaded this scene without any network support.

    Can someone please clarify how to go about doing this? Am I supposed to use the host to listen for the client connect and request a scene change there? Documentation around this is lacking unfortunately.
     
  2. CosmoM

    CosmoM

    Joined:
    Oct 31, 2015
    Posts:
    204
    Upon calling
    NetworkManager.Singleton.StartClient()
    , the client should automatically be switched to the scene of the host, assuming the host loaded it through the NetworkManager too (
    NetworkManager.Singleton.SceneManager.LoadScene(...)
    ).
     
  3. unity_NTyxeB384OxNOQ

    unity_NTyxeB384OxNOQ

    Joined:
    Mar 5, 2019
    Posts:
    4
    In order for the auto sync of scenes to happen, you need to make sure that the NetworkManager's "Enable Scene Management" bool is set to true in the inspector as well :)
     
  4. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Hi, I tried to do it this way, but after I click the host button (that firstly runs this code
    NetworkManager.Singleton.StartHost()
    ) I want to load the next scene by using that code you showed. I previously stored the scene as
    gameScene = SceneManager.GetSceneByBuildIndex(1);
    , and I'm trying this piece of code:
    NetworkManager.Singleton.SceneManager.LoadScene(gameScene.name, LoadSceneMode.Single)
    ;
    however, I'm getting the following error
    The scene is in build list. In fact, I can load the scene pretty easily by using SceneManager. Notwithstanding, I want the scenes to be synchronized with other clients, and that's why I'm trying to get this method done. Any idea of what could be causing this issue?
     
    Last edited: Nov 5, 2022
  5. CosmoM

    CosmoM

    Joined:
    Oct 31, 2015
    Posts:
    204
    That's very strange, you're calling the network scene manager correctly... If the scene is really in the build list then the only thing I can think of is that you're maybe calling LoadScene slightly too fast. What I do myself is subscribe to OnServerStarted and call the scene loader from there:

    Code (CSharp):
    1. void Start() {
    2.     NetworkManager.Singleton.OnServerStarted+=HandleServerStarted;
    3. } //Start
    4.  
    5. private void HandleServerStarted() {
    6.     NetworkManager.Singleton.SceneManager.LoadScene(sceneName,LoadSceneMode.Single);
    7. } //HandleServerStarted
     
  6. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Thanks for the reply. I found what the issue was and I explained on this thread how I fixed it.

    Apparently, the scene name was null because this code:
    gameScene = SceneManager.GetSceneByBuildIndex(1);
    does not retrieve the data correctly.

    Code (CSharp):
    1. gameScenePath = SceneUtility.GetScenePathByBuildIndex(1);
    2. string gameSceneName = System.IO.Path.GetFileNameWithoutExtension(gameScenePath);
    on the other hand did the trick.

    Appart from that, I want to ask something out of curiosity:

    I tried loading the scene with the SceneManager and also with the NetworkManager, but I don't see any difference, they look the same to me. Why is it recommended to do it with the NetworkManager?