Search Unity

Resolved Help with clients loading the host's scene automatically

Discussion in 'Netcode for GameObjects' started by GuirieSanchez, Dec 28, 2022.

  1. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    I found out that clients that reconnect to the game load the host's scene automatically when connecting to the network (I'm using the sample Netcode Bootstrap). I would like to know where in the code they are loading the host's scene because I want to make sure they receive some data before they do so.

    Thank you in advance!
     
  2. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    Hi @GuirieSanchez , what's the Netcode Bootstrap sample you mentioned?
     
    GuirieSanchez likes this.
  3. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Well, I found out the bootstrap sample wasn’t provided by Unity (sorry for the confusion). But I think it’s got nothing to do with it.

    Upon checking the documentation, I realized that as soon as the client has the green light (when the connection is approved at the "NetworkManager.Singleton.ConnectionApprovalCallback"), the client automatically loads the host’s scene before the “OnClientConnected” callback gets called. This is supposed to be done internally and automatically, so I have no clue how to perform some actions before they load the scene (namely sending the server's info to the client via "ClientRpc", which can't be done since the player connecting is not yet a client: it first loads the scene, then the player becomes a client).
     
    Last edited: Jan 3, 2023
  4. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Does anyone experienced get any idea?
     
  5. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    You have two ways to do this:

    1. Use NetworkVariables , which are automatically synchronized when the players reconnect
    2. Send the data as soon as the player connects, through RPCs

    In general, If a player is not connected, you can't send data to them.

    Are these 2 solutions a a viable option for you?
     
  6. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Unfortunately not :/

    I discarted the network variables since I have to update and then send a lot of variables just in a specific moment. But regardless of using a struct and sending it over an RPC call or using network variables, I still face the same problem: the client updates when he connects, which is after the host's scene is loaded (which is too late because I want the updated parameters to have effect on some game object's Awake and Start methods from the host's scene).

    So the only way that occurred to me was to manually load the host's scene after the player is connected and have receive all the updated info.

    Let me know if I didn't explain myself correctly. Also, if you have an alternative in mind, that'll be very helpful too.
     
    Last edited: Jan 4, 2023
  7. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    It sounds like you're doing something similar to this thread in case it helps.
     
    GuirieSanchez likes this.
  8. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    @cerestorm

    Thank you for pointing me to this thread! I feel this could be the answer to my problem

    Could you please elaborate a little bit on
    ?

    I tried using an RPC after the connection is approved but it seems too early. Will the RPC call work when the
    SceneEventType.Synchronize
    callback gets called?


    PS: In case it's relevant to any answer, this is the way I update the client's info:

    (1) upon connecting, a Server RPC is called to update a struct containing all the useful parameters with the server's parameters' values.
    (2) Then a targeted Client RPC is called to send the struct and update the client's parameters' values.

    The system works perfectly but it arrives too late in case I call it on the "OnClientConnected" callback, as I mentioned. If called after the "connection approval" callback, then the Client RPC call doesn't work (since the client is not yet connected).
     
    Last edited: Jan 4, 2023
  9. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    You'd need to use a custom message rather than a RPC, this sends a message between network managers without needing a network object.

    It will be NetworkManager.Singleton.SceneManager.OnSynchronize you'll want to subscribe to. I only did a quick test with it so maybe @CosmoM can chime in and let us know if it worked for him, otherwise I can dig out the test I did but it shouldn't be too hard to set up a new one.
     
    GuirieSanchez likes this.
  10. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Thank you for the help, I really appreciate it.
    I see, I'll be doing research on custom messages since so far I've only used RPCs.

    Got it. I'll be doing some testing. I'll report whatever I find.
     
    cerestorm likes this.
  11. mishakozlov74

    mishakozlov74

    Joined:
    Aug 8, 2018
    Posts:
    143
    Having the same problem here. When my client connects to the host, I'd to show some loading screen before the actual scene.

    Did you find a solution for that?
     
  12. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    I was finishing other parts of the project before delving properly into custom messages, so I couldn't report any solid findings. However, I was using @cerestorm's suggestion about using "NetworkManager.Singleton.SceneManager.OnSynchronize", and it works perfectly: the callback is called when the client is already connected but before the scene is fully loaded, which allows you to send the data before the
    Start()
    method from the host's scene is called (it specifically happens in between the host's scene's
    Awake()
    /
    OnEnable()
    methods and the
    Start()
    method).

    However, I have no idea how to stall or avoid loading the host scene automatically for you to be able to load a custom loading screen.
     
    Last edited: Jan 22, 2023
    mishakozlov74 likes this.
  13. mishakozlov74

    mishakozlov74

    Joined:
    Aug 8, 2018
    Posts:
    143
    Thanks for the answer. I tried custom messages myself - it's a dead end, Netcode doesn't accept it on a client with an error "Trying to receive NamedMessage from client 0 which is not in a connected state."

    I try to send this message during the NetworkManager.Singleton.ConnectionApprovalCallback delegate, maybe I do something wrong.
     
  14. mishakozlov74

    mishakozlov74

    Joined:
    Aug 8, 2018
    Posts:
    143
  15. mishakozlov74

    mishakozlov74

    Joined:
    Aug 8, 2018
    Posts:
    143
    Okay, I figured it out, right after CreateClient.

    But anyway, I tried to send RPC, I tried to send a custom message, I still receive it at the moment when the scene is loaded and active.

    I'm giving up, there must be a way for a client to know that it's about to load a scene and do logic at this moment.

    [UPD]
    Nevermind, managed to do that by subscribing to
    NetworkManager.Singleton.SceneManager.OnSceneEvent right after the ClientStart.

    Ooh, what a roller coaster!
     
    Last edited: Jan 22, 2023