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: docs/basics/networkvariable.md
+29-14Lines changed: 29 additions & 14 deletions
Original file line number
Diff line number
Diff line change
@@ -5,14 +5,15 @@ title: NetworkVariables
5
5
6
6
`NetworkVariable`s are a way of synchronizing properties between servers and clients in a persistent manner, unlike [RPCs](../advanced-topics/message-system/rpc.md) and [custom messages](../advanced-topics/message-system/custom-messages.md), which are one-off, point-in-time communications that aren't shared with any clients not connected at the time of sending. `NetworkVariable`s are session-mode agnostic and can be used with either a [client-server](../terms-concepts/client-server.md) or [distributed authority](../terms-concepts/distributed-authority.md) network topology.
7
7
8
-
`NetworkVariable` is a wrapper of the stored value of type `T`, so you need to use the `NetworkVariable.Value` property to access the actual value being synchronized. A `NetworkVariable`is synchronized with:
8
+
`NetworkVariable` is a wrapper of the stored value of type `T`, so you need to use the `NetworkVariable.Value` property to access the actual value being synchronized. A `NetworkVariable`handles value synchronization for:
9
9
10
10
* New clients joining the game (also referred to as late-joining clients)
11
-
* When the associated NetworkObject of a `NetworkBehaviour` with `NetworkVariable` properties is spawned, any `NetworkVariable`'s current state (`Value`) is automatically synchronized on the client side.
12
-
* Connected clients
13
-
* When a `NetworkVariable` value changes, all connected clients that subscribed to the `NetworkVariable.OnValueChanged` event (prior to the value being changed) are notified of the change. Two parameters are passed to any `NetworkVariable.OnValueChanged` subscribed callback method:
14
-
- First parameter (Previous): The previous value before the value was changed
15
-
- Second parameter (Current): The newly changed `NetworkVariable.Value`
11
+
* All connected clients during the game
12
+
13
+
When using a [distributed authority](../terms-concepts/distributed-authority.md) network topology, A `NetworkVariable` ensures value synchronization is handled during:
14
+
15
+
* Ownership changes of the associated NetworkObject
16
+
* Object redistribution during client connection or disconnection
16
17
17
18
You can use `NetworkVariable`[permissions](#permissions) to control read and write access to `NetworkVariable`s. You can also create [custom `NetworkVariable`s](custom-networkvariables.md).
18
19
@@ -25,13 +26,16 @@ You can use `NetworkVariable` [permissions](#permissions) to control read and wr
25
26
- A `NetworkVariable`'s value can only be set:
26
27
- When initializing the property (either when it's declared or within the Awake method).
27
28
- While the associated NetworkObject is spawned (upon being spawned or any time while it's still spawned).
29
+
- A `NetworkVariable` can't be defined with the `static` keyword. Variables defined with the static keyword have a lifetime that lasts for the entire runtime of an application, rather than the much shorter lifetime of a `GameObject`. This results in incorrect and invalid state management where `NetworkVariable`s don't behave as expected.
28
30
29
-
### Initializing a NetworkVariable
31
+
### Initializing a NetworkVariable
30
32
31
-
When a client first connects, it's synchronized with the current value of the `NetworkVariable`. Typically, clients should register for `NetworkVariable.OnValueChanged` within the `OnNetworkSpawn` method. A `NetworkBehaviour`'s `Start` and `OnNetworkSpawn` methods are invoked based on the type of NetworkObject the `NetworkBehaviour` is associated with:
33
+
When a NetworkObject with an associated `NetworkBehaviour` with `NetworkVariable` properties is spawned, the `NetworkVariable` is initialized and associated with its relevant `NetworkBehaviour`. When any new client connects, it's synchronized with the current value of the `NetworkVariable` before the `NetworkBehaviour.OnNetworkSpawn` is invoked.
34
+
35
+
`NetworkVariable`s are initialized during the associated `NetworkBehaviour` initialization. The [Start](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/MonoBehaviour.Start.html) and `OnNetworkSpawn` methods are invoked based on the type of NetworkObject the `NetworkBehaviour` is associated with:
32
36
33
37
- In-scene placed: Since the instantiation occurs via the scene loading mechanism(s), the `Start` method is invoked before `OnNetworkSpawn`.
34
-
- Dynamically spawned: Since `OnNetworkSpawn` is invoked immediately (that is, within the same relative call-stack) after instantiation, the `Start` method is invoked after `OnNetworkSpawn`.
38
+
- Dynamically spawned: Since `OnNetworkSpawn` is invoked immediately (that is, within the same relative call-stack) after instantiation, the `Start` method is invoked after `OnNetworkSpawn`.
35
39
36
40
Typically, these methods are invoked at least one frame after the NetworkObject and associated `NetworkBehaviour` components are instantiated. The table below lists the event order for dynamically spawned and in-scene placed objects respectively.
37
41
@@ -43,8 +47,17 @@ Start | OnNetworkSpawn
43
47
44
48
You should only set the value of a `NetworkVariable` when first initializing it or if it's spawned. It isn't recommended to set a `NetworkVariable` when the associated NetworkObject isn't spawned.
45
49
50
+
### Using a NetworkVariable
51
+
52
+
After initialization, subscribing to the `NetworkVariable.OnValueChanged` event notifies connected clients of value changes. Clients must be subscribed to this event prior to the value being changed. Typically, clients should register for `NetworkVariable.OnValueChanged` within the `OnNetworkSpawn` method.
53
+
54
+
Two parameters are passed to any `NetworkVariable.OnValueChanged` subscribed callback method:
55
+
56
+
- First parameter (Previous): The previous value before the value was changed
57
+
- Second parameter (Current): The newly changed `NetworkVariable.Value`
58
+
46
59
:::tip
47
-
If you need to initialize other components or objects based on a `NetworkVariable`'s initial synchronized state, then you can use a common method that's invoked on the client side within the `NetworkVariable.OnValueChanged` callback (if assigned) and `NetworkBehaviour.OnNetworkSpawn` method.
60
+
If you need to update other components or objects based on the state of a `NetworkVariable`, then you can use a common method that's invoked within the `NetworkBehaviour.OnNetworkSpawn` method and the `NetworkVariable.OnValueChanged` callback.
48
61
:::
49
62
50
63
## Supported types
@@ -141,8 +154,8 @@ public class TestNetworkVariableSynchronization : NetworkBehaviour
141
154
```
142
155
143
156
If you attach the above script to an in-scene placed NetworkObject, make a standalone build, run the standalone build as a host, and then connect to that host by entering Play Mode in the Editor, you can see (in the console output):
144
-
- The client side `NetworkVariable` value is the same as the server when `NetworkBehaviour.OnNetworkSpawn` is invoked.
145
-
- The client detects any changes made to the `NetworkVariable` after the in-scene placed NetworkObject is spawned.
157
+
- The client side `NetworkVariable` value is the same as the server when `NetworkBehaviour.OnNetworkSpawn` is invoked.
158
+
- The client detects any changes made to the `NetworkVariable` after the in-scene placed NetworkObject is spawned.
146
159
147
160
This works the same way with dynamically spawned NetworkObjects.
148
161
@@ -152,6 +165,8 @@ The [synchronization and notification example](#synchronization-and-notification
152
165
153
166
The `OnValueChanged` example shows a simple server-authoritative `NetworkVariable` being used to track the state of a door (that is, open or closed) using a non-ownership-based server RPC. With `RequireOwnership = false` any client can notify the server that it's performing an action on the door. Each time the door is used by a client, the `Door.ToggleServerRpc` is invoked and the server-side toggles the state of the door. When the `Door.State.Value` changes, all connected clients are synchronized to the (new) current `Value` and the `OnStateChanged` method is invoked locally on each client.
154
167
168
+
It's important to note how [RPCs](../advanced-topics/message-system/rpc.md) can be used in tandem with `NetworkVariable` state. When an `RPC` call is used in tandem with a `NetworkVariable`, the `RPC` handles instantaneous notification of state, while the `NetworkVariable` handles synchronization across clients of that state.
169
+
155
170
```csharp
156
171
publicclassDoor : NetworkBehaviour
157
172
{
@@ -599,7 +614,7 @@ public class TestFixedString : NetworkBehaviour
@@ -628,5 +643,5 @@ public class TestFixedString : NetworkBehaviour
628
643
629
644
630
645
:::note
631
-
The above example uses a pre-set list of strings to cycle through for example purposes only. If you have a predefined set of text strings as part of your actual design then you would not want to use a FixedString to handle synchronizing the changes to `m_TextString`. Instead, you would want to use a `uint` for the type `T` where the `uint` was the index of the string message to apply to `m_TextString`.
646
+
The above example uses a pre-set list of strings to cycle through for example purposes only. If you have a predefined set of text strings as part of your actual design then you would not want to use a FixedString to handle synchronizing the changes to `m_TextString`. Instead, you would want to use a `uint` for the type `T` where the `uint` was the index of the string message to apply to `m_TextString`.
0 commit comments