Skip to content

Commit e24aff1

Browse files
test and style
Updating the SwitchTransformSpaceWhenParented test to validate using various NetworkTransform configurations (i.e. half precision, quaternion, quaternion compressed) while also parenting with world position stays enabled and disabled. Removing trailing space in recent documentation update.
1 parent 885452a commit e24aff1

File tree

2 files changed

+87
-22
lines changed

2 files changed

+87
-22
lines changed

com.unity.netcode.gameobjects/Documentation~/components/core/networkobject.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ To spawn NetworkObjects with ownership use the following:
4747
GetComponent<NetworkObject>().SpawnWithOwnership(clientId);
4848
```
4949
> [!NOTE]
50-
> When using the `SpawnWithOwnership` method, be aware that any component that has owner-specific checks to perform specific actions will not be invoked on the spawn authority side during the spawn sequence. The spawn authority is the server when using a client-server network topology and can be any client when using a distributed authority network topology. Using `SpawnWithOwnership` can impact things like [NetworkTransform](../helper/networktransform.md), when using to an owner authority motion model, and potentially provide undesired parenting artifacts and/or impact your own scripts if you are planning to have the spawn authority make any further post-spawn adjustments within the same frame.
50+
> When using the `SpawnWithOwnership` method, be aware that any component that has owner-specific checks to perform specific actions will not be invoked on the spawn authority side during the spawn sequence. The spawn authority is the server when using a client-server network topology and can be any client when using a distributed authority network topology. Using `SpawnWithOwnership` can impact things like [NetworkTransform](../helper/networktransform.md), when using to an owner authority motion model, and potentially provide undesired parenting artifacts and/or impact your own scripts if you are planning to have the spawn authority make any further post-spawn adjustments within the same frame.
5151
>To avoid potential issues, it's recommended to use `Spawn`, where the spawn authority starts as the owner throughout the spawn sequence, makes adjustments post-spawn, and then immediately follow with a call to `ChangeOwnership`.
5252
5353
To change ownership, use the `ChangeOwnership` method:

com.unity.netcode.gameobjects/Tests/Runtime/NetworkTransform/NetworkTransformSpawnSequences.cs

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,15 @@
44
using NUnit.Framework;
55
using Unity.Netcode.Components;
66
using Unity.Netcode.TestHelpers.Runtime;
7-
87
using UnityEngine;
98
using UnityEngine.TestTools;
109

1110
namespace Unity.Netcode.RuntimeTests
1211
{
13-
[TestFixture(HostOrServer.DAHost, TransformSpace.World)]
14-
[TestFixture(HostOrServer.DAHost, TransformSpace.Local)]
15-
[TestFixture(HostOrServer.Host, TransformSpace.World)]
16-
[TestFixture(HostOrServer.Host, TransformSpace.Local)]
17-
[TestFixture(HostOrServer.Server, TransformSpace.World)]
18-
[TestFixture(HostOrServer.Server, TransformSpace.Local)]
12+
13+
[TestFixture(HostOrServer.DAHost)]
14+
[TestFixture(HostOrServer.Host)]
15+
[TestFixture(HostOrServer.Server)]
1916
internal class NetworkTransformAutoParenting : IntegrationTestWithApproximation
2017
{
2118
public enum TransformSpace
@@ -26,20 +23,20 @@ public enum TransformSpace
2623

2724
protected override int NumberOfClients => 4;
2825

29-
private NetworkObject m_PrefabToSpawn;
26+
private List<NetworkObject> m_PrefabsToSpawn = new List<NetworkObject>();
3027
private NetworkObject m_ParentToSpawn;
3128

3229
private List<NetworkObject> m_ParentInstances = new List<NetworkObject>();
30+
private List<NetworkObject> m_ChildInstances = new List<NetworkObject>();
3331
private NetworkObject m_ChildInstance;
3432
private NetworkObject m_FinalParent;
3533
private ulong m_NetworkObjectIdToValidate;
3634

37-
private TransformSpace m_TransformSpace;
35+
private TransformSpace m_ParentWorldOrLocal;
3836

3937

40-
public NetworkTransformAutoParenting(HostOrServer host, TransformSpace transformSpace) : base(host)
38+
public NetworkTransformAutoParenting(HostOrServer host) : base(host)
4139
{
42-
m_TransformSpace = transformSpace;
4340
}
4441

4542

@@ -134,16 +131,46 @@ private void Update()
134131
}
135132
}
136133

134+
protected override IEnumerator OnTearDown()
135+
{
136+
m_PrefabsToSpawn.Clear();
137+
return base.OnTearDown();
138+
}
137139

138-
protected override void OnServerAndClientsCreated()
140+
private NetworkObject CreatePrefabToSpawn(TransformSpace transformSpace, bool useHalfPrecision, bool useQuaternion, bool compressQuaternion)
139141
{
140-
m_ParentToSpawn = CreateNetworkObjectPrefab("SeqParent").GetComponent<NetworkObject>();
141-
m_PrefabToSpawn = CreateNetworkObjectPrefab("SeqObj").GetComponent<NetworkObject>();
142-
var networkTransform = m_PrefabToSpawn.gameObject.AddComponent<NetworkTransformStateMonitor>();
142+
var prefabToSpawn = CreateNetworkObjectPrefab($"SeqObj[{m_PrefabsToSpawn.Count}]").GetComponent<NetworkObject>();
143+
var networkTransform = prefabToSpawn.gameObject.AddComponent<NetworkTransformStateMonitor>();
143144
networkTransform.SwitchTransformSpaceWhenParented = true;
144-
networkTransform.InLocalSpace = m_TransformSpace == TransformSpace.Local;
145-
var spawnSequenceController = m_PrefabToSpawn.gameObject.AddComponent<SpawnSequenceController>();
145+
// Validates that even if you try to set local space it will be reset to world when 1st spawned
146+
networkTransform.InLocalSpace = transformSpace == TransformSpace.Local;
147+
networkTransform.UseHalfFloatPrecision = useHalfPrecision;
148+
networkTransform.UseQuaternionSynchronization = useQuaternion;
149+
networkTransform.UseQuaternionCompression = compressQuaternion;
150+
var spawnSequenceController = prefabToSpawn.gameObject.AddComponent<SpawnSequenceController>();
146151
spawnSequenceController.Offset = GetRandomVector3(-20.0f, 20.0f);
152+
return prefabToSpawn;
153+
}
154+
155+
/// <summary>
156+
/// Generates objects to spawn.
157+
/// </summary>
158+
protected override void OnServerAndClientsCreated()
159+
{
160+
m_ParentToSpawn = CreateNetworkObjectPrefab("SeqParent").GetComponent<NetworkObject>();
161+
162+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.World, false, false, false));
163+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.Local, false, false, false));
164+
165+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.World, true, false, false));
166+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.Local, true, false, false));
167+
168+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.World, true, true, false));
169+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.Local, true, true, false));
170+
171+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.World, true, true, true));
172+
m_PrefabsToSpawn.Add(CreatePrefabToSpawn(TransformSpace.Local, true, true, true));
173+
147174
base.OnServerAndClientsCreated();
148175
}
149176

@@ -176,6 +203,18 @@ private bool AllClientsSpawnedObject()
176203
return true;
177204
}
178205

206+
private bool AllClientsDespawnedObject()
207+
{
208+
foreach (var networkManager in m_NetworkManagers)
209+
{
210+
if (networkManager.SpawnManager.SpawnedObjects.ContainsKey(m_NetworkObjectIdToValidate))
211+
{
212+
return false;
213+
}
214+
}
215+
return true;
216+
}
217+
179218
private bool AllClientsParented(StringBuilder errorLog)
180219
{
181220
var hadError = false;
@@ -206,7 +245,6 @@ private bool AllClientsParented(StringBuilder errorLog)
206245
/// that all non-authority instances are properly synchronized with parenting and their final transform values.
207246
/// </summary>
208247
[UnityTest]
209-
210248
public IEnumerator SwitchTransformSpaceWhenParented()
211249
{
212250
var authority = GetAuthorityNetworkManager();
@@ -217,7 +255,29 @@ public IEnumerator SwitchTransformSpaceWhenParented()
217255
yield return WaitForConditionOrTimeOut(AllClientsSpawnedParentObject);
218256
AssertOnTimeout($"Timed out waiting for all clients to spawn parent instances!");
219257

220-
m_ChildInstance = SpawnObject(m_PrefabToSpawn.gameObject, authority).GetComponent<NetworkObject>();
258+
foreach (var prefabToSpawn in m_PrefabsToSpawn)
259+
{
260+
yield return SpawnAndTest(prefabToSpawn, true);
261+
yield return SpawnAndTest(prefabToSpawn, false);
262+
}
263+
}
264+
265+
/// <summary>
266+
/// This runs through the entire spawn and parenting validation tests
267+
/// for the prefab passed in while also adjusting whether to parent
268+
/// with world position stays enabled or disabled.
269+
/// </summary>
270+
private IEnumerator SpawnAndTest(NetworkObject prefabToSpawn, bool worldPositionStays)
271+
{
272+
var authority = GetAuthorityNetworkManager();
273+
m_ChildInstance = SpawnObject(prefabToSpawn.gameObject, authority).GetComponent<NetworkObject>();
274+
var networkTransform = m_ChildInstance.GetComponent<NetworkTransformStateMonitor>();
275+
m_ParentWorldOrLocal = worldPositionStays ? TransformSpace.World : TransformSpace.Local;
276+
Assert.False(networkTransform.InLocalSpace, $"{m_ChildInstance.name} should never be in local space when not parented and SwitchTransformSpaceWhenParented is enabled!");
277+
278+
m_EnableVerboseDebug = true;
279+
VerboseDebug($"[Testing][Parenting: {m_ParentWorldOrLocal}][HalfFloat: {networkTransform.UseHalfFloatPrecision}][Quaternion: {networkTransform.UseQuaternionSynchronization}][Compressed Quaternion: {networkTransform.UseQuaternionCompression}]");
280+
m_EnableVerboseDebug = false;
221281
m_NetworkObjectIdToValidate = m_ChildInstance.NetworkObjectId;
222282

223283
var startingParentIndex = Random.Range(0, k_ParentsToSpawn - 1);
@@ -235,7 +295,7 @@ public IEnumerator SwitchTransformSpaceWhenParented()
235295
{
236296
var parentIndex = (j + startingParentIndex) % k_ParentsToSpawn;
237297
var parent = m_ParentInstances[parentIndex];
238-
m_ChildInstance.TrySetParent(parent, m_TransformSpace == TransformSpace.World);
298+
m_ChildInstance.TrySetParent(parent, m_ParentWorldOrLocal == TransformSpace.World);
239299
m_FinalParent = parent;
240300
}
241301
}
@@ -247,8 +307,13 @@ public IEnumerator SwitchTransformSpaceWhenParented()
247307

248308
yield return WaitForConditionOrTimeOut(TransformsMatch);
249309
AssertOnTimeout($"Timed out waiting for all non-authority transforms of the child to match the authority transform of the child {m_ChildInstance.name}!");
250-
}
251310

311+
var name = m_ChildInstance.name;
312+
m_ChildInstance.Despawn();
313+
314+
yield return WaitForConditionOrTimeOut(AllClientsDespawnedObject);
315+
AssertOnTimeout($"Timed out waiting for all clients to despawn {name}!");
316+
}
252317

253318

254319
protected bool TransformsMatch(StringBuilder errorLog)

0 commit comments

Comments
 (0)