Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Bug Calling Rpc in OnNetworkSpawn causes timing issues on the client side!

Discussion in 'Netcode for GameObjects' started by StarOnker, Apr 21, 2024.

  1. StarOnker

    StarOnker

    Joined:
    Apr 20, 2024
    Posts:
    2
    In the code below, I've started a server, and a client is already connected. I created a FirstSpawnObject on the server using the InstantiateAndSpawn method, and the FirstSpawnObject will be in OnNetworkSpawn, and I will also create a SecondSpawnObj with InstantiateAndSpawn.

    Code (CSharp):
    1. #nullable enable
    2. using Unity.Netcode;
    3. using UnityEngine;
    4. public class FirstSpawnObj : NetworkBehaviour
    5. {
    6.     [SerializeField] private GameObject? networkObject;
    7.     public override void OnNetworkSpawn()
    8.     {
    9.         if (IsServer)
    10.         {
    11.             FirstSpawnObj_EveryoneRpc("Start");
    12.             NetworkObject.InstantiateAndSpawn(networkObject, NetworkManager);
    13.             FirstSpawnObj_EveryoneRpc("End");
    14.         }
    15.     }
    16.     [Rpc(SendTo.Everyone)]
    17.     public void FirstSpawnObj_EveryoneRpc(string str) =>
    18.         print($"{nameof(FirstSpawnObj)}{{{str}}}{{{NetworkObjectId}}}: {nameof(FirstSpawnObj_EveryoneRpc)}");
    19. }
    Code (CSharp):
    1. #nullable enable
    2. using Unity.Netcode;
    3. public class SecondSpawnObj : NetworkBehaviour
    4. {
    5.     public override void OnNetworkSpawn()
    6.     {
    7.         if (IsServer) SecondSpawnObj_EveryoneRpc();
    8.     }
    9.     [Rpc(SendTo.Everyone)]
    10.     public void SecondSpawnObj_EveryoneRpc()
    11.     {
    12.         print($"{nameof(SecondSpawnObj)}{{{NetworkObjectId}}}: {nameof(SecondSpawnObj_EveryoneRpc)}");
    13.     }
    14. }
    On the server side, all EveryoneRpc will be executed in the normal order, as shown below
    upload_2024-4-21_20-0-37.jpeg

    However, there is a problem with the order in which the EveryoneRpc is executed on the client side, which will execute the SecondSpawnObj of Everyone first
    Rpc, and then execute the EveryoneRpc of the FirstSpawnObject. Causes timing errors!
    upload_2024-4-21_20-1-1.jpeg

    After I looked at the source code of the Netcode, I guessed that it might be because the SpawnNetworkObjectLocallyCommon method of the NetworkSpawnManager executes OnNetworkSpawn first, and then sends the client to create the Network
    Object, which causes the SecondSpawnObj to be more important on the client than the FirstSpawnObject

    However, such a running logic can lead to a lot of logic errors in the timing, whether it is the sending of Rpc or the index of a NetworkObject based on ulong. So I would like to ask if this bug can be fixed?
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,896
    What is your problem statement here?

    FirstSpawnObj can be replaced by an in-scene placed object. You can reference that, and the server can make any necessary changes when the game starts. If it's the player object, simply perform whatever is needed in the client connected callback.

    SecondSpawnObj needn't send an RPC to clients (no less to everyone) since every client runs OnNetworkSpawn for this object.

    Rule of thumb: never ever rely on clients running RPCs from multiple sources in a given order.