Search Unity

Resolved RPC not executed on the server

Discussion in 'Netcode for GameObjects' started by MiTschMR, Feb 17, 2024.

  1. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    488
    I hope it is not me who has a fundamental lack of understanding how the RPC's work, I am just following the documentation (and for other parts it works without issues...).

    So, I have a gameobject in my scene (fix, not instantiated) with a NetworkObject component as well as a component deriving from NetworkBehaviour (Sync Local Variables) on it:
    upload_2024-2-17_12-51-3.png
    Whenever one of the variables in
    Local Name Variables
    changes, this change is sent to the server and from there to the other clients. The used code is:
    Code (CSharp):
    1. [Rpc(SendTo.Server, RequireOwnership = false)]
    2. private void SyncNameVariableNumberServerRpc(string name, double value)
    3. {
    4.     localNameVariables.Set(name, value);
    5.  
    6.     SyncNameVariableNumberClientRpc(name, value);
    7. }
    8.  
    9. [Rpc(SendTo.NotServer)]
    10. private void SyncNameVariableNumberClientRpc(string name, double value)
    11. {
    12.     localNameVariables.Set(name, value);
    13. }
    Whenever I call the
    SyncNameVariableNumberServerRpc
    method, the following warning message is logged on the server and the method is not executed:

    [Netcode] Deferred messages were received for a trigger of type OnSpawn with key 0, but that trigger was not received within within 1 second(s).
    UnityEngine.Debug:LogWarning (object)
    Unity.Netcode.NetworkLog:LogWarning (string) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.8.1/Runtime/Logging/NetworkLog.cs:28)
    Unity.Netcode.DeferredMessageManager:PurgeTrigger (Unity.Netcode.IDeferredNetworkMessageManager/TriggerType,ulong,Unity.Netcode.DeferredMessageManager/TriggerInfo) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.8.1/Runtime/Messaging/DeferredMessageManager.cs:97)
    Unity.Netcode.DeferredMessageManager:CleanupStaleTriggers () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.8.1/Runtime/Messaging/DeferredMessageManager.cs:82)
    Unity.Netcode.NetworkManager:NetworkUpdate (Unity.Netcode.NetworkUpdateStage) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.8.1/Runtime/Core/NetworkManager.cs:72)
    Unity.Netcode.NetworkUpdateLoop:RunNetworkUpdateStage (Unity.Netcode.NetworkUpdateStage) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.8.1/Runtime/Core/NetworkUpdateLoop.cs:185)
    Unity.Netcode.NetworkUpdateLoop/NetworkPostLateUpdate/<>c:<CreateLoopSystem>b__0_0 () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.8.1/Runtime/Core/NetworkUpdateLoop.cs:268)


    I have no idea why this happens or what to do to fix it.

    Used packages:
    com.unity.netcode.gameobjects: 1.8.1
    com.unity.transport: 2.1.0
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
  3. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    488
    Thanks for the link! Well that's interesting, it is spawned correctly on the host, however not on the other client, there the id won't be set. But why does it stay this way, it should (as in the other thread) spawn automatically. It is also an active object, not inactive. I don't get it, seriously...
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,901
    This gave me a hunch, commonly such issues can occur if you do not adhere to the timing of things. For example you should not call Rpc methods on an object until OnNetworkSpawn has run. Basically don't use any networking methods in Awake.

    Or you may be calling the ServerRpc method on the server. Or on the host which may cause issues due to instant execution. Try adding the defer/delay (something like that) parameter to the attribute.
     
  5. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    I would also check both client and server are in the same scene as having the same network object in a different scene won't match due to a different GlobalObjectIdHash. I did a quick check and that produces the same warning.
     
  6. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    488
    No networking methods are used in Awake, the joining happens on UI button clicks. The player object is instantiated and synced perfectly. As I wrote before, on the server / host the network spawn is called, only a client not.

    I will try this and update once done.

    It is the same scene (first in line in the build, no other scenes in-between).
     
  7. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    Do the GlobalObjectIdHash'es on the NetworkObject components match for both server and client, it would be strange if they didn't but I can't think of anything else to cause the issue. Are you using ParrelSync?
     
  8. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    488
    From what I saw during testing yes, but will print them to the console just to make sure and get back. And no, I am not using ParrelSync, I test with a built client and the editor or two built clients.
     
  9. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    If it's not that it could be a timing issue as CodeSmile said, is the rpc called after the client's OnClientConnectedCallback is triggered?

    I did also notice if you have Spawn With Observers unticked on the NetworkObject you'll get the same warning on the server but it throws an exception on the client as well.
     
  10. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    258
    You should try to avoid using the legacy names for the universal Rpcs.
    Try this adjustment:
    Code (CSharp):
    1. [Rpc(SendTo.Server, RequireOwnership = false)]
    2. private void ServerSyncNameVariableNumberRpc(string name, double value)
    3. {
    4.     localNameVariables.Set(name, value);
    5.     SyncNameVariableNumberClientRpc(name, value);
    6. }
    7. [Rpc(SendTo.NotServer)]
    8. private void ClientSyncNameVariableNumberRpc(string name, double value)
    9. {
    10.     localNameVariables.Set(name, value);
    11. }
     
  11. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    258
    As a side note:
    You can also accomplish the same thing without having to specifying the target in the names like this:

    Code (CSharp):
    1.         [Rpc(SendTo.SpecifiedInParams, RequireOwnership = false)]
    2.         private void SendVariableNameRpc(string name, double value, RpcParams rpcParams = default)
    3.         {
    4.  
    5.         }
    6.  
    7.         private void TestRpc()
    8.         {
    9.             // Send to server
    10.             SendVariableNameRpc("Something", 0.5, RpcTarget.Server);
    11.             // Send to all clients but server
    12.             SendVariableNameRpc("Something", 0.5, RpcTarget.NotServer);
    13.         }
     
  12. MiTschMR

    MiTschMR

    Joined:
    Aug 28, 2018
    Posts:
    488
    Thank you, that was it! I had the setting for
    Spawn With Observers
    deactivated with the false assumption that it would still automatically register etc. It works now as designed.

    Thanks for the suggestion Noel, not accustomed to the concept of the RpcParams as the target yet.
     
  13. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    Good stuff. It seems a little strange that a check isn't made locally preventing non-spawned object rpc's reaching the server, I guess it's just an oversight.