Skip to content

Commit fb99ba2

Browse files
doc: update
Adjusting based on the PR's recent updates. Refactoring the physics section. Moved the NetworkRigidbody content out of physics and into a new NetworkRigidbody section under componetns. Moved physics up to the components layer. Did a large update to the physics documentation and provided an additional walk through of how to "parent" physics bodies using attachables.
1 parent 7d05df9 commit fb99ba2

17 files changed

+501
-44
lines changed

com.unity.netcode.gameobjects/Documentation~/TableOfContents.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131
* [AttachableNode](components/helper/attachablenode.md)
3232
* [ComponentController](components/helper/componentcontroller.md)
3333
* [NetworkAnimator](components/helper/networkanimator.md)
34+
* [NetworkRigidbody](components/helper/networkrigidbody.md)
3435
* [NetworkTransform](components/helper/networktransform.md)
35-
* [Physics](advanced-topics/physics.md)
36+
* [Physics](advanced-topics/physics.md)
3637
* [Ownership and authority](ownership-authority.md)
3738
* [Understanding ownership and authority](basics/ownership.md)
3839
* [Ownership race conditions](basics/race-conditions.md)

com.unity.netcode.gameobjects/Documentation~/advanced-topics/physics.md

Lines changed: 445 additions & 29 deletions
Large diffs are not rendered by default.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# NetworkRigidbody
2+
3+
__NetworkRigidbody__ is a component that sets the Rigidbody of the GameObject into kinematic mode on all non-authoritative instances (except the instance that has authority). Authority is determined by the NetworkTransform component (required) attached to the same GameObject as the NetworkRigidbody. Whether the NetworkTransform is server authoritative (default) or owner authoritative, the NetworkRigidBody authority model will mirror it. That way, the physics simulation runs on the authoritative instance, and the resulting positions synchronize on the non-authoritative instances, each with their RigidBody being Kinematic, without any interference.
4+
5+
## Configuring NetworkRigidbody
6+
7+
![image](../../images/networktransform/NetworkRigidbody-fields.png)
8+
9+
When looking at a __NetworkRigidbody__ within the inspector view, you have three exposed values:
10+
11+
- __Use Rigid Body for Motion__
12+
- When enabled and using a [NetworkTransform](./networktransform.md), the __NetworkTransform__ will use the PhysX position and rotation to synchronize changes during the __FixedUpdate__ loop update stage.
13+
- __Auto Update Kinematic State__
14+
- When enabled, __NetworkRigidbody__ will automatically determine if the current instance should be non-kinematic or kinematic.
15+
- For custom solutions, you can opt to disable this field or derive from [NetworkRigidbodyBase](https://docs.unity3d.com/Packages/[email protected]/api/Unity.Netcode.Components.NetworkRigidbodyBase.html) and design your own custom network rigid body handler.
16+
- __Auto Set Kinematic On Despawn__
17+
- This does exactly what it sounds like. When despawned, it will make the rigid body kinematic (_can be useful for object pools_).
18+
19+
20+
Some collision events aren't fired when using NetworkRigidBody.
21+
- On the `server`, all collision and trigger events (such as `OnCollisionEnter`) fire as expected and you can access (and change) values of the `Rigidbody` (such as velocity).
22+
- On the `clients`, the `Rigidbody` is kinematic. Trigger events still fire but collision events won't fire when colliding with other networked `Rigidbody` instances if your project's physics settings is set the default contact pairs.
23+
![image](../../images/networktransform/ProjectPhysicsSettings.png)
24+
- You can adjust the __Contact Pairs Mode__ to use kinematic and non-kinematic by setting it to __Enable All Contact Pairs__.
25+
![image](../../images/networktransform/ProjectPhysicsSettings2.png)
26+
27+
28+
> [!NOTE]
29+
> If there's a need for a gameplay event to happen on a collision, you can listen to `OnCollisionEnter` function on the server and synchronize the event via `Rpc(SendTo.Everyone)` to all clients. If you plan on handling a bunch of collisions, then it is recommended to use the [RigidbodyContactEventManager](https://docs.unity3d.com/Packages/[email protected]/api/Unity.Netcode.Components.RigidbodyContactEventManager.html) in order to handle collision checking during a job (_`OnCollisionenter` can become expensive from a processing perspective if you have enough instances colliding_).
30+
31+
### NetworkRigidbody2D
32+
33+
`NetworkRigidbody2D` works in the same way as NetworkRigidbody but for 2D physics (`Rigidbody2D`) instead.
34+
35+
### Rigidbody interpolation example
36+
37+
While NetworkTransform offers interpolation as a way to smooth between delta state updates, it doesn't get applied to the authoritative instance. You can use `Rigidbody.interpolation` for your authoritative instance while maintaining a strict server-authoritative motion model.
38+
39+
To have a client control their owned objects, you can use either [RPCs](message-system/rpc.md) or [NetworkVariables](../basics/networkvariable.md) on the client-side. However, this often results in the host-client's updates working as expected, but with slight jitter when a client sends updates. You might be scanning for key or device input during the `Update` to `LateUpdate` stages. Any input from the host player is applied after the `FixedUpdate` stage (i.e. physics simulation for the frame has already run), but input from client players is sent via a message and processed, with a half RTT delay, on the host side (or processed 1 network tick + half RTT if using NetworkVariables). Because of when messages are processed, client input updates run the risk of being processed during the `EarlyUpdate` stage which occurs just before the current frame's `FixedUpdate` stage.
40+
41+
To avoid this kind of scenario, it's recommended that you apply any changes received via messages to a Rigidbody _after_ the FixedUpdate has run for the current frame. If you [look at how NetworkTransform handles its changes to transform state](https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/blob/a2c6f7da5be5af077427eef9c1598fa741585b82/com.unity.netcode.gameobjects/Components/NetworkTransform.cs#L3028), you can see that state updates are applied during the `Update` stage, but are received during the `EarlyUpdate` stage. Following this kind of pattern when synchronizing changes to a Rigidbody via messages will help you to avoid unexpected results in your Netcode for GameObjects project.
42+
43+
The best way to address the issue of physics latency is to create a custom NetworkTransform with a custom physics-based interpolator. You can also use the [Network Simulator tool](https://docs.unity3d.com/Packages/com.unity.multiplayer.tools@latest?subfolder=/manual/network-simulator) to spot issues with latency.

com.unity.netcode.gameobjects/Documentation~/components/helper/networktransform.md

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Sometimes network conditions are poor, with packets experiencing latency and pot
147147
Of course, you might wonder what would happen if 5% of the end of a jumping motion were dropped and how NetworkTransform might recover since each state update sent is only based on axial deltas defined by each axis threshold setting. The answer is that there is a small bandwidth penalty for sending standard delta state updates unreliably, full axial frame synchronization, which assures that in the event there is loss each NetworkTransform will be "auto-corrected" once per second.
148148

149149
> [!NOTE]
150-
> When using a NetworkRigidbody or NetworkRigidbody2D component with the __Use Rigidbody for Motion__ property enabled, you should avoid using the __UseUnreliableDeltas____ NetworkTransform property because it can impact the overall interpolation result when you have multiple Rigidbody-based objects that need to keep relatively synchronized with each other.
150+
> When using a NetworkRigidbody or NetworkRigidbody2D component with the __Use Rigidbody for Motion__ property enabled, you should avoid using the __UseUnreliableDeltas____ NetworkTransform property because it can impact the overall interpolation result when you have multiple Rigidbody-based objects that need to keep relatively synchronized with each other.
151151
152152
#### Unreliable State Updates
153153

@@ -175,19 +175,13 @@ When changing from world space to local space and vice versa, NetworkTransform c
175175

176176
This means that non-authority instances could still have state updates pending to be processed when a NetworkObject is parented (or de-parented) and those buffered state values are still expressed as world (or local) space values. Since parenting is not network tick synchronized, the non-authority instances could still have the previous (world or local space) state updates remaining to be processed. This can create a visual "popping" result on the non-authority instance because it has been placed in a different Transform space while processing the previous Transform space state updates.
177177

178-
To resolve this issue, you can enable the __Switch Transform Space When Parented__ configuration property and the NetworkTransform will automatically detect when its associated NetworkObject has changed its parented status, automatically switch to local or world space (parented or not parented), and convert the pending interpolator(s) states within each respective axis's `BufferedLinearInterpolator` to the appropriate Transform space values. The end result yields a seamless transition between world and local (and vice versa) space when parenting.
178+
To resolve this issue, you can enable the __Switch Transform Space When Parented__ configuration property and let NetworkTransform automatically detect when its associated NetworkObject has changed its parented status, automatically switch to local or world space (parented or not parented), and convert the pending interpolator(s) states within each respective axis's `BufferedLinearInterpolator` to the appropriate Transform space values. The end result yields a seamless transition between world and local (and vice versa) space when parenting. This is the recommended way to handle smooth transitions between world and local space when parenting.
179179

180180
Things to consider when using __Switch Transform Space When Parented__:
181181

182-
- This property isn't synchronized by the authority instance. If you disable it on the authority instance but the default setting in your network prefab is for it to be enabled, non-authority instances will remain enabled.
183-
- You can opt to synchronize this setting via custom script or enabling and disabling it under other certain logical conditions in script (such as having it based on a condition and not synchronized by the authority).
184-
- If you disable __Switch Transform Space When Parented__ and the associated NetworkObject gets parented and you manually switch from world to local space, then you will get the original parenting behavior where the interpolator is not updated when the switch occurs.
185-
- You can opt to disable it while spawning and then make the default to enable it once finished spawning (within `OnNetworkPostSpawn` would be one way to handle this, for example).
186-
- While you can still change __In Local Space__ directly via script while __Switch Transform Space When Parented__ is enabled, this could impact the end results if you then proceed to parent the NetworkObject.
182+
- This property is synchronized by the authority instance. If you disable it on the authority instance then it will synchronize this adjustment on all non-authority instances.
187183
- When using __Switch Transform Space When Parented__, it's best to not make adjustments to the __NetworkTransform.InLocalSpace__ field and let the NetworkTransform handle this for you.
188-
189-
> [!NOTE]
190-
> This feature's intended use is handling smooth transitions between world and local space after the NetworkObject has been spawned and is moving around. It's not intended to solve any issues you might run across if parenting in the middle of the spawn process.
184+
- While you can still change __In Local Space__ directly via script while __Switch Transform Space When Parented__ is enabled, this could impact the end results. It is recommended to not adjust __In Local Space__ when __Switch Transform Space When Parented__ is enabled.
191185

192186
### Parenting
193187

@@ -196,12 +190,15 @@ NetworkObject parenting can become complex when:
196190
- You are parenting a NetworkObject while it's [in motion](#in-motion).
197191
- You are parenting a NetworkObject [while spawning](#when-spawning) (depending upon network topology and the desired authority motion model).
198192

199-
#### In motion
193+
#### Spawning or in motion
194+
195+
The __Switch Transform Space When Parented__ field is intended to smooth the transition between world and local spaces. This setting is specifically designed to handle converting all of the non-authority instance's currently queued `NetworkTransformState`s to the appropriate transform space. When parenting, the transform space is automatically switched to local (transform) space on the authority instance that will then send this change in the transform space on the next network tick. This feature can also handle multiple parenting actions that occur on the same frame or over a few frames that are all within the normal network tick update period.
196+
197+
When __Switch Transform Space When Parented__ is enabled, each parenting action will generate a unique transform message that is immediately added to the outbound message queued to preserve the order of operations. This means for each parenting event that occurs, a transform message will be generated. As such, it is recommended to not parent the same object dozens of times within the same frame to keep message traffic minimalized.
200198

201-
The __Switch Transform Space When Parented__ field is intended to smooth the transition between world and local spaces. This setting is specifically designed to handle converting all of the non-authority instance's currently queued `NetworkTransformState`s to the appropriate transform space. When parenting, the transform space is automatically switched to local (transform) space on the authority instance that will then send this change in the transform space on the next network tick.
202199

203200
> [!NOTE]
204-
> __Switch Transform Space When Parented__ is designed to work with the Unity transform's world and local space capabilities. However, when using a Rigidbody component and setting the NetworkRigidbody to use the Rigidbody for motion, the position and rotation values being synchronized are based on the Rigidbody's position and rotation values and not the Unity transform values. The Rigidbody position and rotation values are separate PhysX values that are adjusted during the `FixedUpdate` update loop stage. Because PhysX has no concept of local space, it's not recommended to enable this field when the authority is synchronizing the Rigidbody's position and rotation values.
201+
> __Switch Transform Space When Parented__ is designed to work with the Unity transform's world and local space capabilities. However, when using a Rigidbody component and setting the NetworkRigidbody to use the Rigidbody for motion, the position and rotation values being synchronized are based on the Rigidbody's position and rotation values and not the Unity transform values. The Rigidbody position and rotation values are separate PhysX values that are adjusted during the `FixedUpdate` update loop stage. Because PhysX has no concept of local space, it's not recommended to enable this field when the authority is synchronizing the Rigidbody's position and rotation values. [You can read more about parenting rigid bodies here](../../advanced-topics//physics.md).
205202
206203
#### When spawning
207204

61.7 KB
Loading
153 KB
Loading
124 KB
Loading
133 KB
Loading
32.8 KB
Loading
241 KB
Loading

0 commit comments

Comments
 (0)