Skip to content

Commit fc43642

Browse files
committed
Update formatting and use NetcodeIntegrationTest for test class
1 parent 6b3963f commit fc43642

File tree

4 files changed

+87
-124
lines changed

4 files changed

+87
-124
lines changed

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabHandler.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ public interface INetworkPrefabInstanceHandler
2020
///
2121
/// Note on Pooling: If you are using a NetworkObject pool, don't forget to make the NetworkObject active
2222
/// via the <see cref="GameObject.SetActive(bool)"/> method.
23-
///
24-
/// If you need to pass custom data at instantiation time (e.g., selecting a variant, setting initialization parameters, or choosing a pre-instantiated object),
25-
/// implement <see cref="INetworkPrefabInstanceHandlerWithData{T}"/> instead.
2623
/// </summary>
24+
/// <remarks>
25+
/// If you need to pass custom data at instantiation time (e.g., selecting a variant, setting initialization parameters, or choosing a pre-instantiated object),
26+
/// implement <see cref="NetworkPrefabInstanceHandlerWithData{T}"/> instead.
27+
/// </remarks>
2728
/// <param name="ownerClientId">the owner for the <see cref="NetworkObject"/> to be instantiated</param>
2829
/// <param name="position">the initial/default position for the <see cref="NetworkObject"/> to be instantiated</param>
2930
/// <param name="rotation">the initial/default rotation for the <see cref="NetworkObject"/> to be instantiated</param>
@@ -120,7 +121,9 @@ public bool AddHandler(uint globalObjectIdHash, INetworkPrefabInstanceHandler in
120121
public void SetInstantiationData<T>(GameObject gameObject, T instantiationData) where T : struct, INetworkSerializable
121122
{
122123
if (gameObject.TryGetComponent<NetworkObject>(out var networkObject))
124+
{
123125
SetInstantiationData(networkObject, instantiationData);
126+
}
124127
}
125128
public void SetInstantiationData<T>(NetworkObject networkObject, T data) where T : struct, INetworkSerializable
126129
{
@@ -238,10 +241,7 @@ public bool RemoveHandler(uint globalObjectIdHash)
238241
m_PrefabInstanceToPrefabAsset.Remove(networkPrefabHashKey);
239242
}
240243

241-
if (m_PrefabAssetToPrefabHandlerWithData.TryGetValue(globalObjectIdHash, out var handlerWithData))
242-
{
243-
m_PrefabAssetToPrefabHandlerWithData.Remove(globalObjectIdHash);
244-
}
244+
m_PrefabAssetToPrefabHandlerWithData.Remove(globalObjectIdHash);
245245
return m_PrefabAssetToPrefabHandler.Remove(globalObjectIdHash);
246246
}
247247

@@ -280,12 +280,9 @@ internal bool TryGetHandlerWithData(uint objectHash, out INetworkPrefabInstanceH
280280
/// <summary>
281281
/// Reads the instantiation data for a given <see cref="NetworkObject.GlobalObjectIdHash"/>
282282
/// </summary>
283-
/// <typeparam name="T"></typeparam>
284-
/// <param name="objectHash"></param>
285-
/// <param name="serializer"></param>
286283
internal FastBufferReader GetInstantiationDataReader(uint objectHash, FastBufferReader fastBufferReader)
287284
{
288-
if (!TryGetHandlerWithData(objectHash, out var _))
285+
if (!TryGetHandlerWithData(objectHash, out _))
289286
{
290287
if (NetworkManager.Singleton.LogLevel <= LogLevel.Developer)
291288
{
@@ -295,8 +292,9 @@ internal FastBufferReader GetInstantiationDataReader(uint objectHash, FastBuffer
295292
}
296293

297294
fastBufferReader.ReadValueSafe(out int dataSize);
298-
int dataStartPos = fastBufferReader.Position;
299-
return new FastBufferReader(fastBufferReader, Collections.Allocator.Temp, dataSize, dataStartPos);
295+
var dataReader = new FastBufferReader(fastBufferReader, Collections.Allocator.Temp, dataSize, fastBufferReader.Position);
296+
fastBufferReader.Seek(dataSize);
297+
return dataReader;
300298
}
301299

302300
/// <summary>
@@ -334,12 +332,16 @@ internal NetworkObject HandleNetworkPrefabSpawn(uint networkPrefabAssetHash, ulo
334332
if (instantiationDataReader.IsInitialized)
335333
{
336334
if (m_PrefabAssetToPrefabHandlerWithData.TryGetValue(networkPrefabAssetHash, out var prefabInstanceHandler))
335+
{
337336
networkObjectInstance = prefabInstanceHandler.Instantiate(ownerClientId, position, rotation, instantiationDataReader);
337+
}
338338
}
339339
else
340340
{
341341
if (m_PrefabAssetToPrefabHandler.TryGetValue(networkPrefabAssetHash, out var prefabInstanceHandler))
342+
{
342343
networkObjectInstance = prefabInstanceHandler.Instantiate(ownerClientId, position, rotation);
344+
}
343345
}
344346
//Now we must make sure this alternate PrefabAsset spawned in place of the prefab asset with the networkPrefabAssetHash (GlobalObjectIdHash)
345347
//is registered and linked to the networkPrefabAssetHash so during the HandleNetworkPrefabDestroy process we can identify the alternate prefab asset.
@@ -393,9 +395,9 @@ public GameObject GetNetworkPrefabOverride(GameObject gameObject)
393395
{
394396
case NetworkPrefabOverride.Hash:
395397
case NetworkPrefabOverride.Prefab:
396-
{
397-
return m_NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[networkObject.GlobalObjectIdHash].OverridingTargetPrefab;
398-
}
398+
{
399+
return m_NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[networkObject.GlobalObjectIdHash].OverridingTargetPrefab;
400+
}
399401
}
400402
}
401403
}

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkPrefabInstanceHandlerWithData.cs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using Unity.Collections;
41
using UnityEngine;
52

63
namespace Unity.Netcode
@@ -12,18 +9,18 @@ namespace Unity.Netcode
129
public abstract class NetworkPrefabInstanceHandlerWithData<T> : INetworkPrefabInstanceHandlerWithData where T : struct, INetworkSerializable
1310
{
1411
public abstract NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation, T instantiationData);
15-
12+
1613
public abstract void Destroy(NetworkObject networkObject);
1714

18-
bool INetworkPrefabInstanceHandlerWithData.HandlesDataType<U>() => typeof(T) == typeof(U);
19-
15+
bool INetworkPrefabInstanceHandlerWithData.HandlesDataType<TK>() => typeof(T) == typeof(TK);
16+
2017
NetworkObject INetworkPrefabInstanceHandlerWithData.Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation, FastBufferReader reader)
2118
{
2219
var startPosition = reader.Position;
23-
reader.ReadValueSafe(out T _payload);
20+
reader.ReadValueSafe(out T payload);
2421
var length = reader.Position - startPosition;
25-
26-
NetworkObject networkObject = Instantiate(ownerClientId, position, rotation, _payload);
22+
23+
NetworkObject networkObject = Instantiate(ownerClientId, position, rotation, payload);
2724
reader.Seek(startPosition);
2825
if (networkObject.InstantiationData == null || networkObject.InstantiationData.Length != length)
2926
{
@@ -41,4 +38,4 @@ internal interface INetworkPrefabInstanceHandlerWithData : INetworkPrefabInstanc
4138
bool HandlesDataType<T>();
4239
NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation, FastBufferReader reader);
4340
}
44-
}
41+
}

com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -807,22 +807,22 @@ internal NetworkObject GetNetworkObjectToSpawn(uint globalObjectIdHash, ulong ow
807807
break;
808808
case NetworkPrefabOverride.Hash:
809809
case NetworkPrefabOverride.Prefab:
810-
{
811-
// When scene management is disabled and this is an in-scene placed NetworkObject, we want to always use the
812-
// SourcePrefabToOverride and not any possible prefab override as a user might want to spawn overrides dynamically
813-
// but might want to use the same source network prefab as an in-scene placed NetworkObject.
814-
// (When scene management is enabled, clients don't delete their in-scene placed NetworkObjects prior to dynamically
815-
// spawning them so the original prefab placed is preserved and this is not needed)
816-
if (inScenePlacedWithNoSceneManagement)
817-
{
818-
networkPrefabReference = networkPrefab.SourcePrefabToOverride ? networkPrefab.SourcePrefabToOverride : networkPrefab.Prefab;
819-
}
820-
else
821810
{
822-
networkPrefabReference = NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[globalObjectIdHash].OverridingTargetPrefab;
811+
// When scene management is disabled and this is an in-scene placed NetworkObject, we want to always use the
812+
// SourcePrefabToOverride and not any possible prefab override as a user might want to spawn overrides dynamically
813+
// but might want to use the same source network prefab as an in-scene placed NetworkObject.
814+
// (When scene management is enabled, clients don't delete their in-scene placed NetworkObjects prior to dynamically
815+
// spawning them so the original prefab placed is preserved and this is not needed)
816+
if (inScenePlacedWithNoSceneManagement)
817+
{
818+
networkPrefabReference = networkPrefab.SourcePrefabToOverride ? networkPrefab.SourcePrefabToOverride : networkPrefab.Prefab;
819+
}
820+
else
821+
{
822+
networkPrefabReference = NetworkManager.NetworkConfig.Prefabs.NetworkPrefabOverrideLinks[globalObjectIdHash].OverridingTargetPrefab;
823+
}
824+
break;
823825
}
824-
break;
825-
}
826826
}
827827
}
828828

com.unity.netcode.gameobjects/Tests/Runtime/Prefabs/NetworkPrefabHandlerWithDataTests.cs

Lines changed: 48 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections;
3+
using System.Collections.Generic;
34
using System.Linq;
45
using NUnit.Framework;
56
using Unity.Netcode.TestHelpers.Runtime;
@@ -8,145 +9,108 @@
89

910
namespace Unity.Netcode.RuntimeTests
1011
{
11-
internal class NetworkPrefabHandlerWithDataTests
12+
internal class NetworkPrefabHandlerWithDataTests : NetcodeIntegrationTest
1213
{
13-
private const int k_ClientCount = 4;
14+
protected override int NumberOfClients => 4;
1415
private const string k_TestPrefabObjectName = "NetworkPrefabTestObject";
15-
private uint m_ObjectId = 1;
16+
private GameObject m_Prefab;
17+
private PrefabInstanceHandlerWithData[] m_ClientHandlers;
1618

17-
private GameObject _prefab;
18-
private NetworkManager server;
19-
private NetworkManager[] clients;
20-
21-
private PrefabInstanceHandlerWithData[] clientHandlers;
22-
23-
[SetUp]
24-
public void Setup()
19+
protected override void OnServerAndClientsCreated()
2520
{
26-
NetcodeIntegrationTestHelpers.Create(k_ClientCount, out server, out clients);
27-
_prefab = CreateNetworkPrefab();
21+
// Creates a network object prefab and registers it to all clients.
22+
m_Prefab = CreateNetworkObjectPrefab(k_TestPrefabObjectName).gameObject;
23+
var authority = GetAuthorityNetworkManager();
2824

29-
RegisterPrefab(server, out _);
30-
31-
clientHandlers = new PrefabInstanceHandlerWithData[clients.Length];
32-
for (int i = 0; i < clients.Length; i++)
25+
m_ClientHandlers = new PrefabInstanceHandlerWithData[NumberOfClients];
26+
var idx = 0;
27+
foreach (var manager in m_NetworkManagers)
3328
{
34-
RegisterPrefab(clients[i], out clientHandlers[i]);
29+
RegisterPrefabHandler(manager, out var handler);
30+
if (manager != authority)
31+
{
32+
m_ClientHandlers[idx] = handler;
33+
idx++;
34+
}
3535
}
3636
}
3737

38-
[TearDown]
39-
public void Teardown()
38+
private PrefabInstanceHandlerWithData m_LateJoinPrefabHandler;
39+
protected override void OnNewClientCreated(NetworkManager networkManager)
4040
{
41-
foreach (var client in clients)
42-
{
43-
client.PrefabHandler.RemoveHandler(_prefab);
44-
client.NetworkConfig.Prefabs.Remove(_prefab);
45-
client.Shutdown();
46-
}
47-
48-
server.PrefabHandler.RemoveHandler(_prefab);
49-
server.NetworkConfig.Prefabs.Remove(_prefab);
50-
server.Shutdown();
41+
// This will register all prefabs from the authority to the newly created client.
42+
base.OnNewClientCreated(networkManager);
5143

52-
UnityEngine.Object.DestroyImmediate(_prefab);
53-
NetcodeIntegrationTestHelpers.Destroy();
44+
RegisterPrefabHandler(networkManager, out var lateJoinPrefabHandler);
45+
m_LateJoinPrefabHandler = lateJoinPrefabHandler;
5446
}
5547

5648
[UnityTest]
5749
public IEnumerator InstantiationPayload_SyncsCorrectly()
5850
{
59-
yield return StartAndWaitForClients();
6051
var data = new NetworkSerializableTest { Value = 12, Value2 = 3.14f };
52+
6153
SpawnPrefabWithData(data);
62-
yield return WaitForAllClientsToSync(data);
54+
55+
yield return WaitForConditionOrTimeOut(() => AllHandlersSynchronized(data));
56+
AssertOnTimeout("Not all handlers synchronized");
6357
}
6458

6559
[UnityTest]
6660
public IEnumerator InstantiationPayload_LateJoinersReceiveData()
6761
{
68-
yield return StartAndWaitForClients();
6962
var data = new NetworkSerializableTest { Value = 42, Value2 = 2.71f };
7063
SpawnPrefabWithData(data);
7164

72-
// Disconnect and destroy one client to simulate late join
73-
var lateJoiner = clients[0];
74-
lateJoiner.Shutdown();
75-
yield return null;
65+
yield return WaitForConditionOrTimeOut(() => AllHandlersSynchronized(data));
66+
AssertOnTimeout("Not all handlers synchronized");
7667

77-
var lateJoinerIndex = 0;
78-
clients[lateJoinerIndex] = NetcodeIntegrationTestHelpers.CreateNewClient(k_ClientCount);
79-
RegisterPrefab(clients[lateJoinerIndex], out clientHandlers[lateJoinerIndex]);
80-
81-
NetcodeIntegrationTestHelpers.StartOneClient(clients[lateJoinerIndex]);
82-
yield return NetcodeIntegrationTestHelpers.WaitForClientConnected(clients[lateJoinerIndex]);
68+
// Late join a client
69+
yield return CreateAndStartNewClient();
8370

8471
// Confirm late joiner got correct data
85-
var timeoutHelper = new TimeoutHelper();
86-
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => clientHandlers[lateJoinerIndex].instantiationData.IsSynchronizedWith(data));
87-
Assert.False(timeoutHelper.TimedOut, "Late joiner did not synchronize properly with instantiation data.");
72+
yield return WaitForConditionOrTimeOut(() => m_LateJoinPrefabHandler.InstantiationData.IsSynchronizedWith(data));
73+
AssertOnTimeout("Late joiner received incorrect data");
8874
}
8975

90-
private GameObject CreateNetworkPrefab()
91-
{
92-
var guid = NetworkManagerHelper.AddGameNetworkObject($"{k_TestPrefabObjectName}{m_ObjectId++}");
93-
var networkObject = NetworkManagerHelper.InstantiatedNetworkObjects[guid];
94-
NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(networkObject);
95-
return networkObject.gameObject;
96-
}
9776

98-
private void RegisterPrefab(NetworkManager manager, out PrefabInstanceHandlerWithData handler)
77+
private void RegisterPrefabHandler(NetworkManager manager, out PrefabInstanceHandlerWithData handler)
9978
{
100-
var networkPrefab = new NetworkPrefab { Prefab = _prefab };
101-
manager.NetworkConfig.Prefabs.Add(networkPrefab);
102-
103-
handler = new PrefabInstanceHandlerWithData(_prefab);
104-
manager.PrefabHandler.AddHandler(_prefab, handler);
79+
handler = new PrefabInstanceHandlerWithData(m_Prefab);
80+
manager.PrefabHandler.AddHandler(m_Prefab, handler);
10581
}
10682

107-
private NetworkObject SpawnPrefabWithData(NetworkSerializableTest data)
83+
private void SpawnPrefabWithData(NetworkSerializableTest data)
10884
{
109-
var instance = GameObject.Instantiate(_prefab).GetComponent<NetworkObject>();
110-
server.PrefabHandler.SetInstantiationData(instance, data);
85+
var instance = UnityEngine.Object.Instantiate(m_Prefab).GetComponent<NetworkObject>();
86+
GetAuthorityNetworkManager().PrefabHandler.SetInstantiationData(instance, data);
11187
instance.Spawn();
112-
return instance;
113-
}
114-
115-
private IEnumerator StartAndWaitForClients()
116-
{
117-
if (!NetcodeIntegrationTestHelpers.Start(true, server, clients))
118-
Assert.Fail("Failed to start instances");
119-
120-
yield return NetcodeIntegrationTestHelpers.WaitForClientsConnected(clients, null, 512);
121-
yield return NetcodeIntegrationTestHelpers.WaitForClientsConnectedToServer(server, clients.Length + 1, null, 512);
12288
}
12389

124-
private IEnumerator WaitForAllClientsToSync(NetworkSerializableTest expectedData)
90+
private bool AllHandlersSynchronized(NetworkSerializableTest expectedData)
12591
{
126-
var timeoutHelper = new TimeoutHelper();
127-
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => clientHandlers.All(h => h.instantiationData.IsSynchronizedWith(expectedData)));
128-
Assert.False(timeoutHelper.TimedOut, "Data did not synchronize correctly to all clients.");
92+
return m_ClientHandlers.All(handler => handler.InstantiationData.IsSynchronizedWith(expectedData));
12993
}
13094

13195
private class PrefabInstanceHandlerWithData : NetworkPrefabInstanceHandlerWithData<NetworkSerializableTest>
13296
{
133-
public GameObject Prefab;
134-
public NetworkSerializableTest instantiationData;
97+
private readonly GameObject m_Prefab;
98+
public NetworkSerializableTest InstantiationData;
13599

136100
public PrefabInstanceHandlerWithData(GameObject prefab)
137101
{
138-
Prefab = prefab;
102+
m_Prefab = prefab;
139103
}
140104

141105
public override NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation, NetworkSerializableTest data)
142106
{
143-
instantiationData = data;
144-
return GameObject.Instantiate(Prefab, position, rotation).GetComponent<NetworkObject>();
107+
InstantiationData = data;
108+
return UnityEngine.Object.Instantiate(m_Prefab, position, rotation).GetComponent<NetworkObject>();
145109
}
146110

147111
public override void Destroy(NetworkObject networkObject)
148112
{
149-
GameObject.DestroyImmediate(networkObject.gameObject);
113+
UnityEngine.Object.DestroyImmediate(networkObject.gameObject);
150114
}
151115
}
152116

0 commit comments

Comments
 (0)