You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: com.unity.netcode.gameobjects/Documentation~/advanced-topics/message-system/rpc.md
+110Lines changed: 110 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -215,6 +215,116 @@ There are a few other parameters that can be passed to either the `Rpc` attribut
215
215
|`Target`| Runtime override destination for the RPC. (See above for more details.) Populating this value will throw an exception unless either the `SendTo` value for the RPC is `SendTo.SpecifiedInParams`, or `AllowTargetOverride` is `true`.<br /><br />Default: `null`|
216
216
|`LocalDeferMode`| Overrides the `DeferLocal` value. `DeferLocalMode.Defer` causes this particular invocation of this RPC to be deferred until the next frame even if `DeferLocal` is `false`, while `DeferLocalMode.SendImmediate` causes the RPC to be executed immediately on the local machine even if `DeferLocal` is `true`. `DeferLocalMode.Default` does whatever the `DeferLocal` value in the attribute is configured to do.<br /><br />Options: `DeferLocalMode.Default`, `DeferLocalMode.Defer`, `DeferLocalMode.SendImmediate`<br />Default: `DeferLocalMode.Default`|
217
217
218
+
## Invocation order
219
+
220
+
Rpc message sent with `RpcDelivery.Reliable` will be sent and invoked on other game clients in the same order as they were called on the local game client.
Debug.Log($"client {rpcParams.Receive.SenderClientId} has opened door {doorId}");
227
+
228
+
// Server can handle door opening here
229
+
}
230
+
231
+
[Rpc(SendTo.Server)]
232
+
voidOpenChestRPC(intchestId, RpcParamsrpcParams)
233
+
{
234
+
Debug.Log($"client {rpcParams.Receive.SenderClientId} has opened chest {chestId}");
235
+
236
+
// Server can handle door opening here
237
+
}
238
+
239
+
voidUpdate()
240
+
{
241
+
if (IsClient&&Input.GetKeyDown(KeyCode.O))
242
+
{
243
+
OpenDoorRpc(1)
244
+
OpenDoorRpc(2)
245
+
OpenChestRpc(5)
246
+
}
247
+
248
+
// Other clients will log:
249
+
//
250
+
// "client 1 has opened door 1"
251
+
// "client 1 has opened door 2"
252
+
// "client 1 has opened chest 5"
253
+
}
254
+
```
255
+
256
+
> [!Warning]
257
+
> Invocation order is not guaranteed with nested RPC invocations that include targets that may invoke locally. Invocation order is also not guaranteed when using `RpcDelivery.Unreliable`
258
+
259
+
### Deferring local invocation
260
+
261
+
Invoking an RPC from within another RPC introduces the risk that the local RPC may invoke before messages are sent to other game clients. This will result in the RPC message for the inner RPC invocation being sent before the message for the outer RPC.
Debug.Log($"client {rpcParams.Receive.SenderClientId} is trying to open door {doorId}");
268
+
269
+
if (HasAuthority) {
270
+
// Authority handles opening the door here
271
+
272
+
// If the authority is invoking TryOpenDoorRpc locally before the authority has sent TryOpenDoorRpc to other clients, OpenDoorRpc will be sent before TryOpenDoorRpc.
Debug.Log($"client {rpcParams.Receive.SenderClientId} marked door {doorId} as open");
281
+
}
282
+
283
+
voidUpdate()
284
+
{
285
+
if (Input.GetKeyDown(KeyCode.O))
286
+
{
287
+
// Invocation of TryOpenDoorRpc and OpenDoorRpc may be inverted depending on the context in which TryOpenDoorRpc is invoked
288
+
TryOpenDoorRpc(20);
289
+
}
290
+
}
291
+
```
292
+
293
+
Use the RPC `LocalDeferMode` to resolve issue. Configuring the RPC to be deferred when invoked locally will ensure that any outer RPC messages are always sent before the inner function is invoked.
294
+
295
+
```csharp
296
+
// An RPC can be configured to defer the local invocation in the attribute definition
0 commit comments