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
> When using `SpawnWithOwnership` method in a client-server network topology you must be aware that during the spawn sequence any component that has owner specific checks to perform specific actions will not be invoked on the server side. This can impact things like [NetworkTransform](../helper/networktransform.md) when set to an owner authority motion model. To avoid issues pertaining to this it is recommended to use `Spawn` where the server is the owner during the spawn sequence and then immediately following that with a call to `ChangeOwnership`. The two actions will get combined into a single `CreateObjectMessage` and will avoid potential, latency driven, issues.
49
51
50
52
To change ownership, use the `ChangeOwnership` method:
51
53
@@ -58,6 +60,9 @@ To give ownership back to the server use the `RemoveOwnership` method:
58
60
```csharp
59
61
GetComponent<NetworkObject>().RemoveOwnership();
60
62
```
63
+
> [!NOTE]
64
+
> It is not recommended to use `RemoveOwnership` when using a distributed authority network topology.
65
+
61
66
62
67
To see if the local client is the owner of a NetworkObject, you can check the [`NetworkBehaviour.IsOwner`](https://docs.unity3d.com/Packages/com.unity.netcode.gameobjects@latest?subfolder=/api/Unity.Netcode.NetworkBehaviour.IsOwner.html) property.
Copy file name to clipboardExpand all lines: com.unity.netcode.gameobjects/Documentation~/components/helper/networktransform.md
+185-1Lines changed: 185 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -178,7 +178,191 @@ When changing from world space to local space and vice versa, NetworkTransform c
178
178
179
179
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.
180
180
181
-
To resolve this issue, you can enable the __Switch Transform Space When Parented__ configuration property and the NetworkTransform will automatically detect when its NetworkObject has changed parented status and convert the pending 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) when parenting.
181
+
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 converts 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.
182
+
183
+
Things to consider when using __Switch Transform Space When Parented__:
184
+
185
+
- This property is not synchronized by the authority instance. This means that if you disable it on the authority instance but the default setting in your network prefab is to be enabled, the non-authority instances will still remain enabled.
186
+
- You can opt to synchronize this setting via custom script or enabling and disabling it under other certain logical conditions in script (i.e. based on a condition and not synchronized by the authority).
187
+
- 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.
188
+
- You can opt to disable it while spawning and then make the default to enable it once finished spawning (i.e. within OnNetworkPostSpawn would be one way to handle this).
189
+
- While you can still change __In Local Space__ directly via script while __Switch Transform Space When Parented__ is enabled, depending upon when you do this could impact the end results if you then proceed to parent the NetworkObject.
190
+
- When using __Switch Transform Space When Parented__, it is best to not make adjustments to the __NetworkTransform.InLocalSpace__ field and let the NetworkTransform handle this for you.
191
+
192
+
193
+
> [!NOTE]
194
+
> This feature's intended usage is handling smooth transitions between world and local space after the NetworkObject has been spawned and is moving around. It is not intended to solve any issues you might run across if parenting while in the middle of the spawn process.
195
+
196
+
197
+
### Parenting
198
+
199
+
NetworkObject parenting can become a complex when:
200
+
- You are parenting a NetworkObject while it is in a state of motion.
201
+
- You are parenting a NetworkObject while spawning (depending upon network topology and the desired authority motion model).
202
+
203
+
#### When in a state of motion
204
+
205
+
We just covered the __Switch Transform Space When Parented__ field and how it can help 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__ 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.
206
+
207
+
> [!NOTE]
208
+
> __Switch Transform Space When Parented__ is designd to work with the Unity transform's world and local space capabilities. However, when using a __Rigidbody__ and setting the __NetworkRigidbody__ to use the rigid body for motion the position and rotation values being synchronized are based on the rigid body's position and rotation values and not the Unity transform values. The rigid body 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 is not recommended to enable this field under the condition that the authority is synchronizing the rigid body's position and rotation values.
209
+
210
+
#### When spawning
211
+
212
+
If you would like to handle parenting during the spawn sequence of a NetworkObject, then it is highly recommended to create a custom __NetworkTransform__ that handles this prior to the __base.OnNetworkSpawn__ method being invoked. This assures that before the __NetworkTransform__ has initialized you have already applied the modifications (parenting and transform adjustments) so that when it does initialize the values are already been applied.
The above works under most conditions, but it can have unexpected results when using:
252
+
- A client-server network topology.
253
+
- An owner authority motion model (when __Authority Mode__ is set to owner).
254
+
- You are spawning with ownership.
255
+
256
+
Since a client-server network topology requires the server (or host) to spawn the object, while the network prefab is spawning on the server side the authority will already have been applied to the NetworkTransform. To avoid issues with this particular scenario, it is recommended that you spawn the network prefab initially with the server as the motion authority and upon finishing the spawn sequence on the server changing ownership to the intended client like this:
257
+
258
+
```c#
259
+
usingUnity.Netcode;
260
+
usingUnityEngine;
261
+
262
+
publicclassObjectSpawner : NetworkBehaviour
263
+
{
264
+
publicNetworkObjectObjectToSpawn;
265
+
// Consider the ParentObject as having already been spawned.
// Both of these calls are collapsed into a single CreateObjectMessage
277
+
instance.Spawn();
278
+
instance.ChangeOwnership(ownerId);
279
+
}
280
+
}
281
+
```
282
+
This results in the spawnd object running through the spawn sequence with the server as the authority to assure any changes are properly applied, and then immediately after invoking the __Spawn__ method it changes ownership. The net-result of these two scripts will generate a single __CreateObjectMessage__.
283
+
284
+
Alternately, when working with an owner authority motion model the inclination might be to handle all of the parenting on the intended owning client side and so it might feel convenient to use __NetworkObject.SpawnWithOwnerhsip__. This results in a series of events that not only could end up with visual anomalies on the host side (if you are using a host vs a server) where the instance on the host side will have an initial spawn position and then after a period of time, driven by the latency between the owning client and the host, the parenting and offset values will be applied to the host-side instance. To further complicate matters, the host then forwards these messages to any other connected client that increases the latency from the moment the object was spawned to the moment it has been parented and an offset applied.
285
+
286
+
The messages generated (under this specific scenario) would be:
287
+
- (Server)
288
+
- Spawns the object
289
+
- One __CreateObjectMessage__ is sent to all connected clients.
290
+
- (Authority Client)
291
+
- Parents the object.
292
+
- One __ParentSyncMessage__ is sent to the host.
293
+
- The host then forwards this to the other clients.
294
+
- Applies an offset.
295
+
- At the end of the current tick when the parenting and offset was applied, a __NetworkTransformMessage__ is generated to update the object's transform values with the offset applied. The delay between the parenting message and this message could be close to the tick frequency (default would be ~33ms)
296
+
- Upon receiving this message, the host forwards it to the rest of the clients.
297
+
298
+
As you can see, not only could you run into visual anomalies due to the time delta between when the object is spawned and the object is both parented and an offset applied which is all dependent upon the latency between the owning client and the host as well as the latency between the host and non-owning clients.
299
+
300
+
To avoid this kind of timing issue, it is recommended (_in a client-server network topology when using an owner authoritative motion model_) to spawn with the server as the initial owner and then changing ownership aftwards where all of the actions (spawning, parenting, and applying a local space offset) are included in the single `CreateObjectMessage`. It reduces the bandwidth cost per spawn and avoids having to deal with the above latency driven timing issues.
301
+
302
+
#### Other options
303
+
304
+
A more recent addition to Netcode for GameObjects is the [AttachableBehaviour](../helper/attachablebehaviour.md) component that provides an alternate way to handle parenting without having to use the traditional __NetworkObject__ parenting approach. Additionally, you might contemplate using the distributed authority network topology since that allows clients to spawn objects locally where they can apply modifications (like they were the host) prior to the `CreateObjectMessage` being sent to all of the other connected clients.
305
+
306
+
### Teleport and SetState
307
+
_(__Teleport__ invokes __SetState__)_
308
+
309
+
There are times when you might want to move an object over a reasonable distance but not have non-authority instances interpolate between the current transform's state and a modified transform state. You can use either __NetworkTransform.Teleport__ or __NetworkTransform.SetState__ to accomplish this. However, it is important to understand the intended usage for both of these methods.
310
+
311
+
#### Intended usage
312
+
- Invoke on already spawned objects.
313
+
- You can invoke these methods during the spawn process, but it is recommended to diretly apply the transform settings when spawning.
314
+
- Invoking either of these methods consumes state updates for the current tick.
315
+
- This means that if you invoke either of these two methods multiple times in a single tick you will only get the current values of the transform. Calls to these two methods __do not__ stack!
316
+
317
+
However, let's say you have a valid reason to do multiple Teleports in a short period of time. How would you do this? Since the the calls to these methods do not stack, you would need some way to be able to handle this.
318
+
319
+
Once again, by creating a custom derived NetworkTransform class the authority side can be notified when it has pushed a state update (like a teleport) by deriving from __NetworkTransform.OnAuthorityPushTransformState__ lets you know when a __NetworkTransformState__ has been pushed on the authority instance.
320
+
321
+
Here is an example of how you could teleport to multiple locations over a short period of time (with 1 network tick between each teleport):
0 commit comments