Skip to content

Commit 0e9d178

Browse files
authored
NetworkBehaviour updates (#1313) (#1314)
1 parent 2bf18a7 commit 0e9d178

37 files changed

+228
-224
lines changed

docs/advanced-topics/client-anticipation.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ The `OnReanticipate` event can also be used for other purposes, such as "forward
9090

9191
## `OnReanticipate` event
9292

93-
`NetworkBehaviour` has a virtual method called `OnReanticipate`. When server data is received for an `AnticipatedNetworkVariable` or `AnticipatedNetworkTransform`, it's rolled back immediately, setting its anticipated state. During each frame in which a server update for any `AnticipatedNetworkVariable` or `AnticipatedNetworkTransform` is received (after **all** such operations have been performed and **all** objects are rolled back to their server state), each `NetworkObject` that had any rollbacks calls the `OnReanticipate` method on **all** of its `NetworkBehaviour`s.
93+
`NetworkBehaviour` has a virtual method called `OnReanticipate`. When server data is received for an `AnticipatedNetworkVariable` or `AnticipatedNetworkTransform`, it's rolled back immediately, setting its anticipated state. During each frame in which a server update for any `AnticipatedNetworkVariable` or `AnticipatedNetworkTransform` is received (after **all** such operations have been performed and **all** objects are rolled back to their server state), each NetworkObject that had any rollbacks calls the `OnReanticipate` method on **all** of its `NetworkBehaviour`s.
9494

9595
If you need to do any reanticipation to update the anticipated state of any of these variables or transforms, this method is where you will do it. `OnReanticipate` takes as its only parameter a `double` providing the amount of time, in seconds, that the object has been rolled back (which corresponds to the round-trip time of the current batch of responses received from the server). This value can be used to calculate the difference between what the server value is, and what the anticipated client value should be, and apply that change.
9696

docs/advanced-topics/inscene_parenting_player.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ public class ParentPlayerToInSceneNetworkObject : NetworkBehaviour
8080
}
8181
```
8282

83-
You should place this script on your in-scene placed `NetworkObject` (that is, the first `GameObject`) and do the parenting from it to avoid any timing issues of when it's spawned or the like. It only runs the script on the server-host side since parenting is server authoritative.
83+
You should place this script on your in-scene placed NetworkObject (that is, the first `GameObject`) and do the parenting from it to avoid any timing issues of when it's spawned or the like. It only runs the script on the server-host side since parenting is server authoritative.
8484

8585

8686
:::note
87-
Remove any parenting code you might have had from your player Prefab before using the above script. Depending upon your project's goals, you might be parenting all players under the same in-scene placed `NetworkObject` or you might intend to have each player parenting unique. If you want each player to be parented under a unique in-scene placed `NetworkObject` then you will need to have the same number of in-scene placed `NetworkObject`s as your maximum allowed players per game session. The above example will only parent all players under the same in-scene placed `NetworkObject`. You can extend the above example by migrating the scene event code into an in-scene placed `NetworkObject` that manages the parenting of players (i,e. name it something like `PlayerSpawnManager`) as they connect, make the `SetPlayerParent` method public, and add all in-scene placed `NetworkObject`s to a public list of GameObjects that the `PlayerSpawnManager` will reference and assign player's to as they connect while also freeing in-scene placed `NetworkObject`s as players disconnect during a game session.
87+
Remove any parenting code you might have had from your player Prefab before using the above script. Depending upon your project's goals, you might be parenting all players under the same in-scene placed NetworkObject or you might intend to have each player parenting unique. If you want each player to be parented under a unique in-scene placed NetworkObject then you will need to have the same number of in-scene placed NetworkObjects as your maximum allowed players per game session. The above example will only parent all players under the same in-scene placed NetworkObject. You can extend the above example by migrating the scene event code into an in-scene placed NetworkObject that manages the parenting of players (i,e. name it something like `PlayerSpawnManager`) as they connect, make the `SetPlayerParent` method public, and add all in-scene placed NetworkObjects to a public list of GameObjects that the `PlayerSpawnManager` will reference and assign player's to as they connect while also freeing in-scene placed NetworkObjects as players disconnect during a game session.
8888
:::
8989

9090
:::important

docs/advanced-topics/message-system/clientrpc.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ The host is both a client and a server. If a host invokes a client RPC, it trigg
116116
<ImageSwitcher
117117
lightImageSrc="/sequence_diagrams/RPCs/ClientRPCs_ClientHosts_CalledByClientHost.png?text=LightMode"
118118
darkImageSrc="/sequence_diagrams/RPCs/ClientRPCs_ClientHosts_CalledByClientHost_Dark.png?text=DarkMode"/>
119-
<figcaption>Hosts can invoke client RPCs on `NetworkObjects`. If broadcasting to all clients, the RPC will be immediately invoked on the host and placed in the local queue. At the end of the frame, the client RPC will be sent to the remote clients. When a remote client receives the client RPC it's executed on the client's local cloned instance of the same `NetworkObject`.</figcaption>
119+
<figcaption>Hosts can invoke client RPCs on `NetworkObjects`. If broadcasting to all clients, the RPC will be immediately invoked on the host and placed in the local queue. At the end of the frame, the client RPC will be sent to the remote clients. When a remote client receives the client RPC it's executed on the client's local cloned instance of the same NetworkObject.</figcaption>
120120
</figure>
121121

122122
:::warning

docs/advanced-topics/message-system/reliabilty.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ void MyReliableServerRpc() { /* ... */ }
2424
void MyUnreliableServerRpc() { /* ... */ }
2525
```
2626

27-
Reliable RPCs will be received on the remote end in the same order they are sent, but this in-order guarantee only applies to RPCs on the same `NetworkObject`. Different `NetworkObjects` might have reliable RPCs called but executed in different order compared to each other. To put more simply, **in-order reliable RPC execution is guaranteed per `NetworkObject` basis only**. If you determine an RPC is being updated often (that is, several times per second), it _might_ be better suited as an unreliable RPC.
27+
Reliable RPCs will be received on the remote end in the same order they are sent, but this in-order guarantee only applies to RPCs on the same NetworkObject. Different `NetworkObjects` might have reliable RPCs called but executed in different order compared to each other. To put more simply, **in-order reliable RPC execution is guaranteed per NetworkObject basis only**. If you determine an RPC is being updated often (that is, several times per second), it _might_ be better suited as an unreliable RPC.
2828
:::caution
2929
When testing unreliable RPCs on a local network, the chance of an unreliable packet being dropped is reduced greatly (sometimes never). As such, you might want to use [`UnityTransport`'s Simulator Pipeline](https://docs-multiplayer.unity3d.com/transport/current/pipelines#simulator-pipeline) to simulate poor network conditions to better determine how dropped unreliable RPC messages impacts your project.
3030
:::

docs/advanced-topics/message-system/serverrpc.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class SomeNetworkBehaviour : NetworkBehaviour
2727
}
2828
}
2929
```
30-
The above example uses the default [ServerRpc] attribute settings which only allows a client owner (client that owns `NetworkObject` associated with the `NetworkBehaviour` containing the `ServerRpc` method) invocation rights. Any client that isn't the owner won't be allowed to invoke the `ServerRpc`.
30+
The above example uses the default [ServerRpc] attribute settings which only allows a client owner (client that owns NetworkObject associated with the `NetworkBehaviour` containing the `ServerRpc` method) invocation rights. Any client that isn't the owner won't be allowed to invoke the `ServerRpc`.
3131

3232
## ServerRpc Ownership And ServerRpcParams
3333
There are times where you might want any client to have `ServerRpc` invocation rights. You can easily accomplish this by setting the `ServerRpc` attribute's `RequireOwnership` parameter to false like in the example below:
@@ -142,14 +142,14 @@ The following are a few timing diagrams to help provide additional visual contex
142142
<ImageSwitcher
143143
lightImageSrc="/sequence_diagrams/RPCs/ServerRPCs.png?text=LightMode"
144144
darkImageSrc="/sequence_diagrams/RPCs/ServerRPCs_Dark.png?text=DarkMode"/>
145-
<figcaption>A Client can invoke a server RPC on a `NetworkObject`. The RPC will be placed in the local queue and then sent to the server at the end of the frame. Upon receiving the server RPC, it's executed on the Server's instance of the same `NetworkObject`.</figcaption>
145+
<figcaption>A Client can invoke a server RPC on a NetworkObject. The RPC will be placed in the local queue and then sent to the server at the end of the frame. Upon receiving the server RPC, it's executed on the Server's instance of the same NetworkObject.</figcaption>
146146
</figure>
147147

148148
<figure>
149149
<ImageSwitcher
150150
lightImageSrc="/sequence_diagrams/RPCs/ServerRPCs_ClientHosts_CalledByClient.png?text=LightMode"
151151
darkImageSrc="/sequence_diagrams/RPCs/ServerRPCs_ClientHosts_CalledByClient_Dark.png?text=DarkMode"/>
152-
<figcaption>Clients can invoke server RPCs on Hosts exactly like they can on a Server: the RPC will be placed in the local queue and sent to the Host at the end of the frame. Upon receiving the server RPC, it will be executed on the Host's instance of the same `NetworkObject`.</figcaption>
152+
<figcaption>Clients can invoke server RPCs on Hosts exactly like they can on a Server: the RPC will be placed in the local queue and sent to the Host at the end of the frame. Upon receiving the server RPC, it will be executed on the Host's instance of the same NetworkObject.</figcaption>
153153
</figure>
154154

155155
<figure>

docs/advanced-topics/networkobject-parenting.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ If you plan on parenting in-scene placed NetworkObject components with a player
8181

8282
When using the `NetworkObject.TrySetParent` or `NetworkObject.TryRemoveParent` methods, the `WorldPositionStays` parameter is synchronized with currently connected and late joining clients. When removing a child from its parent, use the same `WorldPositionStays` value that you used to parent the child. More specifically, when `WorldPositionStays` is false, this applies. However, if you're using the default value of `true`, this isn't required (because it's the default).
8383

84-
When the `WorldPositionStays` parameter in `NetworkObject.TrySetParent` is the default value of `true`, this will preserve the world space values of the child `NetworkObject` relative to the parent. However, sometimes you might want to only preserve the local space values (pick up an object that only has some initial changes to the child's transform when parented). Through a combination of `NetworkObject.TrySetParent` and `NetworkBehaviour.OnNetworkObjectParentChanged` you can accomplish this without the need for a NetworkTransform component. To better understand how this works, it's important to understand the order of operations for both of these two methods:
84+
When the `WorldPositionStays` parameter in `NetworkObject.TrySetParent` is the default value of `true`, this will preserve the world space values of the child NetworkObject relative to the parent. However, sometimes you might want to only preserve the local space values (pick up an object that only has some initial changes to the child's transform when parented). Through a combination of `NetworkObject.TrySetParent` and `NetworkBehaviour.OnNetworkObjectParentChanged` you can accomplish this without the need for a NetworkTransform component. To better understand how this works, it's important to understand the order of operations for both of these two methods:
8585

8686
**Server-Side**
8787

docs/advanced-topics/object-pooling.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ You can register your own spawn handlers by including the `INetworkPrefabInstanc
1717
void Destroy(NetworkObject networkObject);
1818
}
1919
```
20-
Netcode will use the `Instantiate` and `Destroy` methods in place of default spawn handlers for the `NetworkObject` used during spawning and despawning. Because the message to instantiate a new `NetworkObject` originates from a Host or Server, both won't have the Instantiate method invoked. All clients (excluding a Host) will have the instantiate method invoked if the `INetworkPrefabInstanceHandler` implementation is registered with `NetworkPrefabHandler` (`NetworkManager.PrefabHandler`) and a Host or Server spawns the registered/associated `NetworkObject`.
20+
Netcode will use the `Instantiate` and `Destroy` methods in place of default spawn handlers for the NetworkObject used during spawning and despawning. Because the message to instantiate a new NetworkObject originates from a Host or Server, both won't have the Instantiate method invoked. All clients (excluding a Host) will have the instantiate method invoked if the `INetworkPrefabInstanceHandler` implementation is registered with `NetworkPrefabHandler` (`NetworkManager.PrefabHandler`) and a Host or Server spawns the registered/associated NetworkObject.
2121

2222
The following example is from the Boss Room Sample. It shows how object pooling is used to handle the different projectile objects. In that example, the class `NetworkObjectPool` is the data structure containing the pooled objects and the class `PooledPrefabInstanceHandler` is the handler implementing `INetworkPrefabInstanceHandler`.
2323

docs/advanced-topics/serialization/networkobject-serialization.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ description: Brief explanation on using NetworkObject and NetworkBehaviour in Ne
66

77
`GameObjects`, `NetworkObjects` and `NetworkBehaviour` aren't serializable types so they can't be used in `RPCs` or `NetworkVariables` by default.
88

9-
There are two convenience wrappers which can be used to send a reference to a `NetworkObject` or a `NetworkBehaviour` over RPCs or `NetworkVariables`.
9+
There are two convenience wrappers which can be used to send a reference to a NetworkObject or a `NetworkBehaviour` over RPCs or `NetworkVariables`.
1010

1111
## NetworkObjectReference
1212

13-
`NetworkObjectReference` can be used to serialize a reference to a `NetworkObject`. It can only be used on already spawned `NetworkObjects`.
13+
`NetworkObjectReference` can be used to serialize a reference to a NetworkObject. It can only be used on already spawned `NetworkObjects`.
1414

15-
Here is an example of using `NetworkObject` reference to send a target `NetworkObject` over an RPC:
15+
Here is an example of using NetworkObject reference to send a target NetworkObject over an RPC:
1616
```csharp
1717
public class Weapon : NetworkBehaviour
1818
{
@@ -56,12 +56,12 @@ public class Weapon : NetworkBehaviour
5656
}
5757
```
5858
:::note
59-
The implicit conversion to `NetworkObject` / `GameObject` will result in `Null` if the reference can't be found.
59+
The implicit conversion to NetworkObject / `GameObject` will result in `Null` if the reference can't be found.
6060
:::
6161

6262
## NetworkBehaviourReference
6363

64-
`NetworkBehaviourReference` works similar to `NetworkObjectReference` but is used to reference a specific `NetworkBehaviour` component on a spawned `NetworkObject`.
64+
`NetworkBehaviourReference` works similar to `NetworkObjectReference` but is used to reference a specific `NetworkBehaviour` component on a spawned NetworkObject.
6565

6666
```cs
6767
public class Health : NetworkBehaviour
@@ -90,6 +90,6 @@ public class Weapon : NetworkBehaviour
9090

9191
## How NetworkObjectReference & NetworkBehaviourReference work
9292

93-
`NetworkObjectReference` and `NetworkBehaviourReference` are convenience wrappers which serialize the id of a `NetworkObject` when being sent and on the receiving end retrieve the corresponding ` ` with that id. `NetworkBehaviourReference` sends an additional index which is used to find the right `NetworkBehaviour` on the `NetworkObject`.
93+
`NetworkObjectReference` and `NetworkBehaviourReference` are convenience wrappers which serialize the id of a NetworkObject when being sent and on the receiving end retrieve the corresponding ` ` with that id. `NetworkBehaviourReference` sends an additional index which is used to find the right `NetworkBehaviour` on the NetworkObject.
9494

9595
Both of them are structs implementing the `INetworkSerializable` interface.

docs/advanced-topics/session-management.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ You can also decide to clear all data when a session completes or add a timeout
2626

2727
The best way to reconnect players depends on your game. For example, if you use a [Player Object](../basics/networkobject.md#player-objects), a new `Default Player Prefab` automatically spawns when a player connects to the game (including when they reconnect). You can use the player's earlier saved session data to update that object so that it returns to the same state before disconnecting. In those cases, you would need to keep all the important data that you want to restore and map it to the player using your identification system. You can save this data when a player disconnects or update it periodically. You can then use the `OnNetworkSpawn` event on the Player Object's `NetworkBehavior`(s) to get this data and apply it where needed.
2828

29-
In cases where we don't use the Player Object approach and instead manually attribute client ownership to `NetworkObject`(s), we can keep the objects that a player owns when they disconnect, and set the reconnected player as their new owner. To accomplish this, the only data we would need to keep would be the mapping between those objects and their owning player's identifier, then when a player reconnects we can use this mapping to set them as the new owner. This mapping can be as simple as a dictionary mapping the player identifier with the `NetworkObjectId`(s) of the `NetworkObject`(s) they own. Then, in the `OnClientConnectedCallback` from the `NetworkManager`, the server can set the ownership of these objects.
29+
In cases where we don't use the Player Object approach and instead manually attribute client ownership to NetworkObject(s), we can keep the objects that a player owns when they disconnect, and set the reconnected player as their new owner. To accomplish this, the only data we would need to keep would be the mapping between those objects and their owning player's identifier, then when a player reconnects we can use this mapping to set them as the new owner. This mapping can be as simple as a dictionary mapping the player identifier with the `NetworkObjectId`(s) of the NetworkObject(s) they own. Then, in the `OnClientConnectedCallback` from the `NetworkManager`, the server can set the ownership of these objects.
3030

3131
Here is an example from the Boss Room sample, showing some simple session management. The game uses the Player Object approach and a GUID to identify unique players.
3232

docs/advanced-topics/ways-to-synchronize.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ The Netcode for GameObjects messaging system allows you to send and receive mess
1919

2020
### Remote procedure calls (RPCs)
2121

22-
RPCs are a way of sending an event notification as well as a way of handling direct communication between a server and a client, or between clients and the [distributed authority service](../terms-concepts/distributed-authority.md). This is sometimes useful when the ownership scope of the `NetworkBehavior`, that the remote procedure call is declared within, belongs to the server but you still want one or more clients to be able to communicate with the associated `NetworkObject`.
22+
RPCs are a way of sending an event notification as well as a way of handling direct communication between a server and a client, or between clients and the [distributed authority service](../terms-concepts/distributed-authority.md). This is sometimes useful when the ownership scope of the `NetworkBehavior`, that the remote procedure call is declared within, belongs to the server but you still want one or more clients to be able to communicate with the associated NetworkObject.
2323

2424
Usage examples:
2525

0 commit comments

Comments
 (0)