Search Unity

[Netcode] Deferred messages were received for NetworkObject #8, but it did not spawn within 1 second

Discussion in 'Netcode for GameObjects' started by cerestorm, Mar 11, 2022.

  1. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    I have a network object with one object instantiated and spawned for each client, and only the client has visibility on its object. When I send a client RPC from one of these objects it's sent to all clients, and due to that object not existing on that client they getting the above warning.

    Explaining it another way. Object A is spawned on Client A, Object B is spawned on Client B. If the server sends a client RPC from Object A, it goes to Client A as it should, but also Client B as well, as Object A doesn't exist on Client B they get the deferred message warning.

    I should be able to get around this by using ClientRpcParams, but is it my responsibility to keep track of this, or should the server already be aware and handling it?
     
  2. cosminunity

    cosminunity

    Joined:
    Mar 4, 2021
    Posts:
    14
    Hei @cerestorm.

    To better assist you with this. For your scenario, do you use the Network Hide/Show functionality? It seems that you want only to spawn a NetworkObject for the specific client but not for the others?

    Greetings,
    Cosmin
     
  3. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    Hi Cosmin, yes I have it so all network objects are hidden by default, and show them to clients as required. In this case I have a MessageService network object, I channel all messages between client and server here through RPC's. One of these objects is spawned for each client and only made visible to them.

    It appears when the server sends a client RPC it broadcasts to all clients, without checking that the object is visible on that actual client. Incidentally I have scene management disabled but I don't think it's a factor as I've seen the same behaviour with it enabled in another project.
     
  4. cosminunity

    cosminunity

    Joined:
    Mar 4, 2021
    Posts:
    14
    Hey, @cerestorm.

    You are right, we've done some digging and it seems that the __endSendClientRpc seems to ignore the Observers List and as such it send the RPC to all connections regardless if they have the NetworkObject spawned or not.

    I've logged this bug internally.

    Greetings,
    Cosmin
     
    Last edited: Mar 18, 2022
    cerestorm likes this.
  5. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    Great news, many thanks Cosmin.
     
  6. NoelStephens_Unity

    NoelStephens_Unity

    Unity Technologies

    Joined:
    Feb 12, 2022
    Posts:
    259
    @cerestorm
    This is being looking into currently.
    While we look into a potentially better solution, here is one way you could handle the issue you are having (using the current pre-release package):
    Code (CSharp):
    1.     public class SomeNetworkBehaviour : NetworkBehaviour
    2.     {
    3.         private ClientRpcParams m_ClientRpcParams = new ClientRpcParams();
    4.         private List<ulong> m_CurrentClientObservers = new List<ulong>();
    5.         private int m_NumberToSend = 0;
    6.  
    7.         private void Awake()
    8.         {
    9.             m_ClientRpcParams.Send.TargetClientIds = m_CurrentClientObservers;
    10.         }
    11.  
    12.         [ClientRpc]
    13.         public void SendNumberClientRpc(int number, ClientRpcParams clientRpcParams = default)
    14.         {
    15.             // Process RPC
    16.         }
    17.  
    18.         public void UpdateNumberToClients(int number)
    19.         {
    20.             var observers = NetworkObject.GetObservers();
    21.             m_CurrentClientObservers.Clear();
    22.             while (observers.MoveNext())
    23.             {
    24.                 m_CurrentClientObservers.Add(observers.Current);
    25.             }
    26.             SendNumberClientRpc(m_NumberToSend, m_ClientRpcParams);
    27.         }
    28.     }
    The above code snippet shows how to specify which clients should receive an RPC using the ClientRpcParams parameter (should always be the last parameter of the RPC). It uses the NetworkObject's current observers to populate the TargetClientIds that is used to determines which clients will be sent the ClientRpc message. When no ClientRpcParams are specified, the default behavior is to broadcast to all clients.

    Side Note:
    If there is any form of state data being sent via the RPC then you may need to update newly added observers with the current state data.
     
    cerestorm likes this.
  7. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    664
    I'd not looked into getting the observers, many thanks for the example.