Search Unity

Question ServerRpc Called twice

Discussion in 'Netcode for GameObjects' started by BurnEmDown, Aug 31, 2022.

  1. BurnEmDown

    BurnEmDown

    Joined:
    Dec 29, 2019
    Posts:
    28
    I have a host and a client, the host is trying to spawn a prefab, and I do that with this method, which is called from a button press

    Code (CSharp):
    1. public void CreateChunks () {
    2.         if(!IsServer) return;
    3.         SpawnerController.Instance.SpawnChunkServerRpc(chunkPrefab);
    4. }
    The ServerRpc method looks like this:

    Code (CSharp):
    1. [ServerRpc]
    2. public void SpawnChunkServerRpc(HexGridChunk chunkPrefab)
    3. {
    4.         //if (chunkPrefab)
    5.         {
    6.             HexGridChunk chunk = Instantiate(chunkPrefab);
    7.             chunk.GetComponent<NetworkObject>().Spawn();
    8.         }
    9. }
    For some reason, it's being called twice. I checked with debugging to make sure and the CreateChunks() method is only being called once.
    The first time that the SeverRpc method is being called, the chunkPrefab is null, which causes an error with this stacktrace:

    Code (CSharp):
    1. NullReferenceException
    2. UnityEngine.Object.Instantiate[T] (T original) (at <a0ef933b1aa54b668801ea864e4204fe>:0)
    3. SpawnerController.SpawnChunkServerRpc (HexGridChunk chunkPrefab) (at Assets/Scripts/SpawnerController.cs:61)
    4. SpawnerController.__rpc_handler_2692164904 (Unity.Netcode.NetworkBehaviour target, Unity.Netcode.FastBufferReader reader, Unity.Netcode.__RpcParams rpcParams) (at <022d067f7ef14d398ee91bdbe33df528>:0)
    5. Unity.Netcode.RpcMessageHelpers.Handle (Unity.Netcode.NetworkContext& context, Unity.Netcode.RpcMetadata& metadata, Unity.Netcode.FastBufferReader& payload, Unity.Netcode.__RpcParams& rpcParams) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Messaging/Messages/RpcMessages.cs:77)
    6. Rethrow as Exception: Unhandled RPC exception!
    7. UnityEngine.Debug:LogException(Exception)
    8. Unity.Netcode.RpcMessageHelpers:Handle(NetworkContext&, RpcMetadata&, FastBufferReader&, __RpcParams&) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Messaging/Messages/RpcMessages.cs:81)
    9. Unity.Netcode.ServerRpcMessage:Handle(NetworkContext&) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Messaging/Messages/RpcMessages.cs:122)
    10. Unity.Netcode.NetworkBehaviour:__endSendServerRpc(FastBufferWriter&, UInt32, ServerRpcParams, RpcDelivery) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Core/NetworkBehaviour.cs:93)
    11. SpawnerController:SpawnChunkServerRpc(HexGridChunk) (at Assets/Scripts/SpawnerController.cs:58)
    12. HexGrid:CreateChunks() (at Assets/Scripts/Hex/HexGrid.cs:306)
    13. <>c:<Start>b__8_4() (at Assets/Scripts/NetworkUI.cs:89)
    14. UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:385)
    Immediately after that it's being called again, this time with the prefab not being null, which is then successfully instantiated and spawned for the client as well.
    I tried to ignore the first call using an "if" check, however when it isn't commented out, for some reason there is no 2nd call and the prefab won't be instantiated and spawned.

    If I then click on the button again and again in the same session, there will only be one call, with the prefab not being null and thus the instantiation & spawning will work correctly without any errors except for the very first time the button is clicked.

    The two calls also have different callstacks, this is for the first one (with the prefab being null):

    Code (CSharp):
    1. SpawnerController.SpawnChunkServerRpc()at F:\Repos\Unity3D\project\Assets\Scripts\SpawnerController.cs:line 59 [2]
    2. SpawnerController.__rpc_handler_2692164904()
    3. RpcMessageHelpers.Handle()at F:\Repos\Unity3D\project\Library\PackageCache\com.unity.netcode.gameobjects@1.0.1\Runtime\Messaging\Messages\RpcMessages.cs:line 77
    4. ServerRpcMessage.Handle()
    5. NetworkBehaviour.__endSendServerRpc()
    6. SpawnerController.SpawnChunkServerRpc() [1]
    7. HexGrid.CreateChunks()
    8. NetworkUI.<>c.<Start>b__8_4()
    9. InvokableCall.Invoke()
    10. UnityEvent.Invoke()
    11. Button.Press()
    12. Button.OnPointerClick()
    13. ExecuteEvents.Execute()
    14. ExecuteEvents.Execute<IPointerClickHandler>()
    15. StandaloneInputModule.ReleaseMouse()
    16. StandaloneInputModule.ProcessMousePress()
    17. StandaloneInputModule.ProcessMouseEvent()
    18. StandaloneInputModule.ProcessMouseEvent()
    19. StandaloneInputModule.Process()
    20. EventSystem.Update()
    And this is for the second one (with the prefab being correct):

    Code (CSharp):
    1. SpawnerController.SpawnChunkServerRpc()at F:\Repos\Unity3D\project\Assets\Scripts\SpawnerController.cs:line 59
    2. HexGrid.CreateChunks()at F:\Repos\Unity3D\project\Assets\Scripts\Hex\HexGrid.cs:line 306
    3. NetworkUI.<>c.<Start>b__8_4()
    4. InvokableCall.Invoke()
    5. UnityEvent.Invoke()
    6. Button.Press()
    7. Button.OnPointerClick()
    8. ExecuteEvents.Execute()
    9. ExecuteEvents.Execute<IPointerClickHandler>()
    10. StandaloneInputModule.ReleaseMouse()
    11. StandaloneInputModule.ProcessMousePress()
    12. StandaloneInputModule.ProcessMouseEvent()
    13. StandaloneInputModule.ProcessMouseEvent()
    14. StandaloneInputModule.Process()
    15. EventSystem.Update()
    I'd like to know why is the ServerRpc being called twice and how can I deal with it to remove the error
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    666
    Check to see what's happening at this line. Are you sure it's not a mouse click event causing the first rpc call?
     
  3. BurnEmDown

    BurnEmDown

    Joined:
    Dec 29, 2019
    Posts:
    28
    It's a mouse click because the method is called via button clicked. What's going on there is that the button gets assigned the method:


    Code (CSharp):
    1. spawnObjectsButton.onClick.AddListener(() =>
    2. {
    3.             HexGrid.Instance.CreateChunks();
    4. });
    The HexGrid.Instance.CreateChunks(); line is 89.

    Should I initialize the button's methods in the editor and not via script?
     
  4. BurnEmDown

    BurnEmDown

    Joined:
    Dec 29, 2019
    Posts:
    28
    I just tried setting the button's method via editor and not via script, I'm still getting an error and then a succesful initialize and spawn. This is the errorstack:


    Code (CSharp):
    1. NullReferenceException
    2. UnityEngine.Object.Instantiate[T] (T original) (at <a0ef933b1aa54b668801ea864e4204fe>:0)
    3. SpawnerController.SpawnChunkServerRpc (HexGridChunk chunkPrefab) (at Assets/Scripts/SpawnerController.cs:61)
    4. SpawnerController.__rpc_handler_2692164904 (Unity.Netcode.NetworkBehaviour target, Unity.Netcode.FastBufferReader reader, Unity.Netcode.__RpcParams rpcParams) (at <95c793b78a99416286717370ef0f2503>:0)
    5. Unity.Netcode.RpcMessageHelpers.Handle (Unity.Netcode.NetworkContext& context, Unity.Netcode.RpcMetadata& metadata, Unity.Netcode.FastBufferReader& payload, Unity.Netcode.__RpcParams& rpcParams) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Messaging/Messages/RpcMessages.cs:77)
    6. Rethrow as Exception: Unhandled RPC exception!
    7. UnityEngine.Debug:LogException(Exception)
    8. Unity.Netcode.RpcMessageHelpers:Handle(NetworkContext&, RpcMetadata&, FastBufferReader&, __RpcParams&) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Messaging/Messages/RpcMessages.cs:81)
    9. Unity.Netcode.ServerRpcMessage:Handle(NetworkContext&) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Messaging/Messages/RpcMessages.cs:122)
    10. Unity.Netcode.NetworkBehaviour:__endSendServerRpc(FastBufferWriter&, UInt32, ServerRpcParams, RpcDelivery) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.1/Runtime/Core/NetworkBehaviour.cs:93)
    11. SpawnerController:SpawnChunkServerRpc(HexGridChunk) (at Assets/Scripts/SpawnerController.cs:58)
    12. HexGrid:CreateChunks() (at Assets/Scripts/Hex/HexGrid.cs:306)
    13. UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:385)
     
  5. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    666
    You can add listeners either way, I add by script, if you use that method it's a good idea to call RemoveAllListeners before adding a new one.

    It looks like the rpc is falling over part way through, you could try removing the HexGridChunk chunkPrefab that you're sending over and just have a debug log inside the rpc. It doesn't help explain why it's being triggered twice though.

    I'm not sure of the problem, if you make the project available I can take a look at it.
     
  6. BurnEmDown

    BurnEmDown

    Joined:
    Dec 29, 2019
    Posts:
    28
    I see, the issue was indeed related to the prefab being sent to the SpawnerController script.
    I tried moving the prefab to be a serializefield of that script and changed the method to not accept any arguments, and then there was no error or any unnecessary call to the constructor.

    I wonder tho, does this mean that for any prefab that I'd like to spawn dynamically, I have to keep it as a serializefield of SpawnerController?
     
  7. BurnEmDown

    BurnEmDown

    Joined:
    Dec 29, 2019
    Posts:
    28
    If I do have to keep the prefabs in the SpawnerController, that could be a big issue since I need to get the instantiated object somehow in the rest of the script which is calling the instantiation and spawning ServerRpc method... I guess I can open another thread for it