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
{{ message }}
This repository was archived by the owner on Jul 23, 2025. It is now read-only.
Copy file name to clipboardExpand all lines: docs/advanced-topics/message-system/rpc.md
+2-7Lines changed: 2 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,25 +5,20 @@ title: Rpc
5
5
import ImageSwitcher from '@site/src/ImageSwitcher.js';
6
6
7
7
8
-
Any process can communicate with any other process by sending an RPC. Starting in version 1.8, the `Rpc` attribute encompasses Server to Client Rpcs, Client to Server Rpcs, and Client to Client Rpcs.
8
+
Any process can communicate with any other process by sending an RPC. Starting in version 1.8, the `Rpc` attribute encompasses server to client RPCs, client to server RPCs, and client to client RPCs.
You can declare an RPC by marking a method with the `[Rpc]` attribute and including the `Rpc` suffix in the method name. RPCs have a number of possible targets that can be declared at both runtime and compile time, but a default must be passed to the `[Rpc]` attribute. For example, to create an RPC that will be executed on the server, you would declare it like this:
@@ -58,7 +53,7 @@ While client-to-client RPCs are supported, it is important to note that there ar
58
53
59
54
## Invoking an RPC
60
55
61
-
You can invoke an RPC by invoking the function directly with parameters:
56
+
You can invoke an RPC by invoking the function directly with parameters. The following code is a heavily simplified example of a server to client RPC and a client to server RPC, with additional logic removed to display only the most basic features of an RPC.
Copy file name to clipboardExpand all lines: docs/advanced-topics/serialization/cprimitives.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,9 @@ id: cprimitives
3
3
title: C# primitives
4
4
---
5
5
6
-
C# primitive types will be serialized by built-in serialization code. These types include `bool`, `char`, `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `float`, `double`, and `string`.
6
+
C# primitive types are serialized by built-in serialization code. These types include `bool`, `char`, `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `float`, `double`, and `string`.
7
+
8
+
You can also serialize [arrays](serialization-arrays.md) of C# primitive types, with the exception of arrays of `strings` (`string[]`) for [performance reasons](serialization-arrays.md#performance-considerations).
Copy file name to clipboardExpand all lines: docs/advanced-topics/serialization/serialization-arrays.md
+20-10Lines changed: 20 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,18 +3,27 @@ id: arrays
3
3
title: Arrays and native containers
4
4
---
5
5
6
-
Arrays of [C# primitive types](cprimatives.md), like `int[]`, and [Unity primitive types](unity-primitives.md), such as `Vector3`, are serialized by built-in serialization code. Otherwise, any array of types that aren't handled by the built-in serialization code, such as `string[]`, needs to be handled through a container class or structure that implements the [`INetworkSerializable`](inetworkserializable.md) interface.
6
+
Netcode for GameObjects has built-in serialization code for arrays of [C# value-type primitives](cprimitives.md), like `int[]`, and [Unity primitive types](unity-primitives.md). Any arrays of types that aren't handled by the built-in serialization code, such as `string[]`, need to be handled using a container class or structure that implements the [`INetworkSerializable`](inetworkserializable.md) interface.
7
+
8
+
## Performance considerations
9
+
10
+
Sending arrays and strings over the network has performance implications. An array incurs a garbage collected allocation, and a string also incurs a garbage collected allocation, so an array of strings results in an allocation for every element in the array, plus one more for the array itself.
11
+
12
+
For this reason, arrays of strings (`string[]`) aren't supported by the built-in serialization code. Instead, it's recommended to use `NativeArray<FixedString*>` or `NativeList<FixedString*>`, because they're more efficient and don't incur garbage collected memory allocation. Refer to [`NativeArray<T>`](#nativearrayt) and [`NativeList<T>`](#nativelistt) below for more details.
13
+
14
+
## Built-in primitive types example
15
+
16
+
Using built-in primitive types is fairly straightforward:
7
17
8
-
## Built-In Primitive Types Example
9
-
Using built-in primitive types is fairly straight forward:
There are many ways to handle sending an array of managed types.
17
-
The below example is a simple `string` container class that implements `INetworkSerializable` and can be used as an array of "StringContainers":
23
+
## INetworkSerializable implementation example
24
+
25
+
There are many ways to handle sending an array of managed types. The following example is a simple `string` container class that implements `INetworkSerializable` and can be used as an array of "StringContainers":
@@ -42,11 +51,12 @@ public class StringContainer : INetworkSerializable
42
51
}
43
52
```
44
53
45
-
## Native Containers
54
+
## Native containers
46
55
47
-
Netcode for GameObjects supports `NativeArray` and `NativeList` native containers with built-in serialization, RPCs, and NetworkVariables. However, you cannot nest either of these containers without causing a crash.
56
+
Netcode for GameObjects supports `NativeArray` and `NativeList` native containers with built-in serialization, RPCs, and NetworkVariables. However, you can't nest either of these containers without causing a crash.
48
57
49
58
A few examples of nesting that will cause a crash:
59
+
50
60
*`NativeArray<NativeList<T>>`
51
61
*`NativeList<NativeArray<T>>`
52
62
*`NativeArray<NativeArray<T>>`
@@ -59,6 +69,7 @@ To serialize a `NativeArray` container, use `serializer.SerializeValue(ref Array
59
69
### `NativeList<T>`
60
70
61
71
To serialize a `NativeList` container, you must:
72
+
62
73
1. Ensure your assemblies reference `Collections`.
63
74
2. You must add `UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT` to your **Scriptiong Define Symbols** list.
64
75
1. From the Unity Editor top bar menu, go to **Edit** > **Project Settings...** > **Player**.
@@ -71,8 +82,7 @@ To serialize a `NativeList` container, you must:
71
82
When using `NativeLists` within `INetworkSerializable`, the list `ref` value must be a valid, initialized `NativeList`.
72
83
73
84
NetworkVariables are similar that the value must be initialized before it can receive updates.
74
-
For example,
75
-
`public NetworkVariable<NativeList<byte>> ByteListVar = new NetworkVariable<NativeList<byte>>{Value = new NativeList<byte>(Allocator.Persistent)};`
85
+
For example, `public NetworkVariable<NativeList<byte>> ByteListVar = new NetworkVariable<NativeList<byte>>{Value = new NativeList<byte>(Allocator.Persistent)};`.
Copy file name to clipboardExpand all lines: docs/learn/rpcvnetvar.md
+28-29Lines changed: 28 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,99 +5,99 @@ sidebar_label: RPC vs NetworkVariable
5
5
---
6
6
import ImageSwitcher from '@site/src/ImageSwitcher.js';
7
7
8
-
Choosing the wrong data syncing mecanism can create bugs, generate too much bandwidth and add too much complexity to your code.
9
-
Netcode for GameObjects (Netcode) has two main ways of syncing information between players. `RPC` ([Remote Procedure Call](../advanced-topics/messaging-system)) and replicated state[(NetworkVariable)](../basics/networkvariable). They both send messages over the network. The logic and your design around how they send messages is what will make you choose one over the other.
8
+
Choosing the wrong data syncing mechanism can create bugs, use too much bandwidth, and add too much complexity to your code.
9
+
Netcode for GameObjects (Netcode) has two main ways of syncing information between players: RPCs ([Remote Procedure Calls](../advanced-topics/messaging-system.md)) and replicated states[(`NetworkVariable`s)](../basics/networkvariable). They both send messages over the network. The logic and your design around how they send messages is what will make you choose one over the other.
10
10
11
-
## Choosing between NetworkVariables or RPCs
11
+
## Choosing between `NetworkVariable`s or RPCs
12
12
13
-
- Use `RPC`s for transient events, information only useful for a moment when it's received.
13
+
- Use RPCs for transient events, information only useful for a moment when it's received.
14
14
- Use `NetworkVariable`s for persistent states, for information that will be around more than a moment.
15
15
16
16
A quick way to choose which to use is to ask yourself: "Should a player joining mid-game get that information?"
<figcaption>Network Variables allow to seamlessly catch up late joining clients by sending the current state as soon as the tick happens.</figcaption>
23
23
</figure>
24
24
25
25
Using the Boss Room's door as an example. A player's client needs to receive the information that the door is open to play the right animations.
26
26
27
-
If we sent an `RPC` to all clients, then all players connecting midgame after that `RPC` are sent will miss that information and have the wrong visual on their clients.
27
+
If we sent an RPC to all clients, then all players connecting mid-game after that RPC is sent will miss that information and have the wrong visual on their clients.
It uses a `BoolNetworkVariable` to represent the "IsOpen" state. If I open the door and a player connects after this, the host will replicate all the world's information to that new player, including the door's state.
43
+
It uses a `BoolNetworkVariable` to represent the `IsOpen` state. If one player opens the door and a second player connects after this, the host replicates all the world's information to that new player, including the door's state.
44
+
45
+
`NetworkVariable`s are eventually consistent. This means not all value changes will be synced, contrary to RPCs, where five calls to an RPC will produce five RPC sends on the network.
44
46
45
-
NetworkVariables are eventually consistent. This means not all value changes will be synced, contrary to RPCs, where 5 calls to an RPC will produce 5 RPC sends on the network.
<figcaption>Network Variables can be updated multiple times between ticks, but only the latest will be synced to other peers.</figcaption>
51
52
</figure>
52
53
53
-
NetworkVariables will save on bandwidth for you, making sure to only send values when the data has changed. However, if you want all value changes, RPCs might be best.
54
+
`NetworkVariable`s will save on bandwidth for you, making sure to only send values when the data has changed. However, if you want all value changes, RPCs might be best.
55
+
56
+
## Why not use `NetworkVariable`s for everything?
54
57
58
+
RPCs are simpler.
55
59
56
-
## Why not use NetworkVariables for everything?
60
+
If you have a temporary event like an explosion, you don't need a replicated state for this. It would not make sense. You would have an "unexploded" state that would need to be synced every time a new player connected? From a design perspective, you might not want to represent these events as state.
57
61
58
-
`RPC`s are simpler.
62
+
An explosion can use an RPC for the event, but the effect of the explosion should be using `NetworkVariable`s (for example player's knockback and health decrease). A newly connected player doesn't care about an explosion that happened five seconds ago. They do care about the current health of the players around that explosion though.
59
63
60
-
If you have a temporary event like an explosion, you don't need a replicated state for this. It would not make sense. You would have an "unexploded" state that would need to be synced everytime a new player connected? From a design perspective, you might not want to represent these events as state.
64
+
Actions in Boss Room are a great example for this. The area of effect action (`AoeAction`) triggers an RPC when the action is activated (showing a VFX around the affected area). The imp's health (`NetworkVariable`s) is updated. If a new player connects, they will see the damaged imps. We would not care about the area of effect ability's VFX, which works great with a transient RPC.
61
65
62
-
An explosion can use an `RPC` for the event, but the effect of the explosion should be using `NetworkVariable`s ( for example player's knockback and health decrease). A newly connected player doesn't care about an explosion that happened 5 seconds ago. They do care about the current health of the players around that explosion though.
63
-
64
-
Actions in Boss Room are a great example for this. The area of effect action (`AoeAction`) triggers an `RPC` when the action is activated (showing a VFX around the affected area). The imp's health (`NetworkVariable`s) is updated. If a new player connects, they will see the damaged imps. We would not care about the area of effect ability's VFX, which works great with a transient `RPC`.
65
-
66
-
`AoeActionInput.cs` Shows the input being updated client side and not waiting for the server. It then calls an `RPC` when clicking on the area to affect.
66
+
`AoeActionInput.cs` Shows the input being updated client side and not waiting for the server. It then calls an RPC when clicking on the area to affect.
`AOEAction.cs`Server side logic detecting enemies inside the area and applying damage. It then broadcasts an `RPC` to tell all clients to play the VFX at the appropriate position. Character's state will automatically update with their respective `NetworkVariable`s update (health and alive status for example).
72
+
`AOEAction.cs`has server-side logic detecting enemies inside the area and applying damage. It then broadcasts an RPC to tell all clients to play the VFX at the appropriate position. Character's state will automatically update with their respective `NetworkVariable`s update (health and alive status for example).
<figcaption>To ensure that several different Network Variables are all synchronized at the same exact time we can use client RPC to join these value changes together.</figcaption>
`NetworkVariable`s are great for managing state, to make sure everyone has the latest value. Use them when you want to make sure newly connected players get an up to date world state.
114
114
115
-
`RPC`s are great for sending transient events. Use them when transmiting short lived events.
116
-
115
+
RPCs are great for sending transient events. Use them when transmitting short-lived events.
0 commit comments