Skip to content

Commit 89dd4c0

Browse files
committed
Test refactor and included late joining test
1 parent 7f6c9c7 commit 89dd4c0

4 files changed

Lines changed: 90 additions & 73 deletions

File tree

com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public uint PrefabIdHash
5959

6060
/// <summary>
6161
/// InstantiationData sent during the instantiation process.
62-
/// Retrieved in <see cref="INetworkPrefabInstanceHandlerWithData.OnSynchronizeInstantiationData{T}(ref BufferSerializer{T})"/>
62+
/// Retrieved in <see cref="INetworkPrefabInstanceHandlerWithData.ReadInstantiationData{T}(ref BufferSerializer{T})"/>
6363
/// and available to INetworkPrefabInstanceHandler.Instantiate() for custom handling by user code.
6464
/// </summary>
6565
internal byte[] InstantiationData;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public interface INetworkPrefabInstanceHandlerWithData<T> : INetworkPrefabInstan
1515
NetworkObject INetworkPrefabInstanceHandler.Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation) => Instantiate(ownerClientId, position, rotation, _table[this]);
1616
void INetworkPrefabInstanceHandlerWithData.RemoveDataEntry(INetworkPrefabInstanceHandlerWithData instance) => _table.Remove(instance);
1717
bool INetworkPrefabInstanceHandlerWithData.HandlesDataType<U>() => typeof(T) == typeof(U);
18-
void INetworkPrefabInstanceHandlerWithData.OnReadInstantiationData<RW>(ref BufferSerializer<RW> serializer)
18+
void INetworkPrefabInstanceHandlerWithData.ReadInstantiationData<RW>(ref BufferSerializer<RW> serializer)
1919
{
2020
_table.TryGetValue(this, out var value);
2121
serializer.SerializeValue(ref value);
@@ -33,7 +33,7 @@ public interface INetworkPrefabInstanceHandlerWithData : INetworkPrefabInstanceH
3333
/// <summary>
3434
/// Invoked during deserialization to read the instantiation data associated with this prefab instance.
3535
/// </summary>
36-
void OnReadInstantiationData<Y>(ref BufferSerializer<Y> serializer) where Y : IReaderWriter;
36+
void ReadInstantiationData<T>(ref BufferSerializer<T> serializer) where T : IReaderWriter;
3737

3838
/// <summary>
3939
/// Removes the data entry for the given instance.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ internal void ReadInstantiationData<T>(uint objectHash, ref BufferSerializer<T>
272272

273273
try
274274
{
275-
synchronizableHandler.OnReadInstantiationData(ref serializer);
275+
synchronizableHandler.ReadInstantiationData(ref serializer);
276276
}
277277
catch (Exception ex)
278278
{

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

Lines changed: 86 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -10,142 +10,159 @@ namespace Unity.Netcode.RuntimeTests
1010
{
1111
internal class NetworkPrefabHandlerWithDataTests
1212
{
13-
private GameObject _prefab;
13+
private const int k_ClientCount = 4;
14+
private const string k_TestPrefabObjectName = "NetworkPrefabTestObject";
15+
private uint m_ObjectId = 1;
1416

17+
private GameObject _prefab;
1518
private NetworkManager server;
1619
private NetworkManager[] clients;
17-
const int k_clientCount = 4;
1820

19-
private PrefabInstanceHandlerWithData server_handler;
20-
private PrefabInstanceHandlerWithData[] client_handlers;
21-
22-
private const string k_TestPrefabObjectName = "NetworkPrefabTestObject";
23-
private uint m_ObjectId = 1;
24-
private GameObject MakeValidNetworkPrefab()
25-
{
26-
Guid baseObjectID = NetworkManagerHelper.AddGameNetworkObject(k_TestPrefabObjectName + m_ObjectId.ToString());
27-
NetworkObject validPrefab = NetworkManagerHelper.InstantiatedNetworkObjects[baseObjectID];
28-
NetcodeIntegrationTestHelpers.MakeNetworkObjectTestPrefab(validPrefab);
29-
m_ObjectId++;
30-
return validPrefab.gameObject;
31-
}
21+
private PrefabInstanceHandlerWithData[] clientHandlers;
3222

3323
[SetUp]
3424
public void Setup()
3525
{
36-
NetcodeIntegrationTestHelpers.Create(k_clientCount, out server, out clients);
37-
38-
_prefab = MakeValidNetworkPrefab();
26+
NetcodeIntegrationTestHelpers.Create(k_ClientCount, out server, out clients);
27+
_prefab = CreateNetworkPrefab();
3928

40-
NetworkPrefab networkPrefab = new NetworkPrefab() { Prefab = _prefab };
29+
RegisterPrefab(server, out _);
4130

42-
server.NetworkConfig.Prefabs.Add(networkPrefab);
43-
server_handler = new PrefabInstanceHandlerWithData(_prefab);
44-
server.PrefabHandler.AddHandler(_prefab, server_handler);
45-
46-
client_handlers = new PrefabInstanceHandlerWithData[clients.Length];
31+
clientHandlers = new PrefabInstanceHandlerWithData[clients.Length];
4732
for (int i = 0; i < clients.Length; i++)
4833
{
49-
client_handlers[i] = new PrefabInstanceHandlerWithData(_prefab);
50-
clients[i].NetworkConfig.Prefabs.Add(networkPrefab);
51-
clients[i].PrefabHandler.AddHandler(_prefab, client_handlers[i]);
34+
RegisterPrefab(clients[i], out clientHandlers[i]);
5235
}
5336
}
5437

5538
[TearDown]
5639
public void Teardown()
5740
{
58-
for (int i = 0; i < clients.Length; i++)
41+
foreach (var client in clients)
5942
{
60-
clients[i].PrefabHandler.RemoveHandler(_prefab);
61-
clients[i].NetworkConfig.Prefabs.Remove(_prefab);
62-
clients[i].Shutdown();
43+
client.PrefabHandler.RemoveHandler(_prefab);
44+
client.NetworkConfig.Prefabs.Remove(_prefab);
45+
client.Shutdown();
6346
}
6447

6548
server.PrefabHandler.RemoveHandler(_prefab);
6649
server.NetworkConfig.Prefabs.Remove(_prefab);
6750
server.Shutdown();
6851

6952
UnityEngine.Object.DestroyImmediate(_prefab);
53+
NetcodeIntegrationTestHelpers.Destroy();
7054
}
7155

7256
[UnityTest]
7357
public IEnumerator InstantiationPayload_SyncsCorrectly()
7458
{
75-
// Start the instances
76-
if (!NetcodeIntegrationTestHelpers.Start(true, server, clients))
77-
{
78-
Debug.LogError("Failed to start instances");
79-
Assert.Fail("Failed to start instances");
80-
}
59+
yield return StartAndWaitForClients();
60+
var data = new NetworkSerializableTest { Value = 12, Value2 = 3.14f };
61+
SpawnPrefabWithData(data);
62+
yield return WaitForAllClientsToSync(data);
63+
}
8164

82-
// [Client-Side] Wait for a connection to the server
83-
yield return NetcodeIntegrationTestHelpers.WaitForClientsConnected(clients, null, 512);
65+
[UnityTest]
66+
public IEnumerator InstantiationPayload_LateJoinersReceiveData()
67+
{
68+
yield return StartAndWaitForClients();
69+
var data = new NetworkSerializableTest { Value = 42, Value2 = 2.71f };
70+
SpawnPrefabWithData(data);
8471

85-
// [Host-Side] Check to make sure all clients are connected
86-
yield return NetcodeIntegrationTestHelpers.WaitForClientsConnectedToServer(server, clients.Length + 1, null, 512);
72+
// Disconnect and destroy one client to simulate late join
73+
var lateJoiner = clients[0];
74+
lateJoiner.Shutdown();
75+
yield return null;
8776

88-
//Sets the values to synchronize
89-
var instantiationData = new NetworkSerializableTest() { Value = 12, Value2 = 3.14f };
77+
var lateJoinerIndex = 0;
78+
clients[lateJoinerIndex] = NetcodeIntegrationTestHelpers.CreateNewClient(k_ClientCount);
79+
RegisterPrefab(clients[lateJoinerIndex], out clientHandlers[lateJoinerIndex]);
9080

91-
// Spawn the prefab on the server
92-
var instance = GameObject.Instantiate<NetworkObject>(_prefab.GetComponent<NetworkObject>());
93-
instance.InjectInstantiationData(instantiationData);
94-
instance.Spawn();
95-
Assert.NotNull(instance);
81+
NetcodeIntegrationTestHelpers.StartOneClient(clients[lateJoinerIndex]);
82+
yield return NetcodeIntegrationTestHelpers.WaitForClientConnected(clients[lateJoinerIndex]);
9683

97-
// wait for the clients to receive the instantiation payload
84+
// Confirm late joiner got correct data
9885
var timeoutHelper = new TimeoutHelper();
99-
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => client_handlers.All(handler => handler.networksSerializableToSynchronize.IsSynchronizedWith(instantiationData)));
100-
Assert.False(timeoutHelper.TimedOut, "Did not successfully sync all handlers");
86+
yield return NetcodeIntegrationTest.WaitForConditionOrTimeOut(() => clientHandlers[lateJoinerIndex].instantiationData.IsSynchronizedWith(data));
87+
Assert.False(timeoutHelper.TimedOut, "Late joiner did not synchronize properly with instantiation data.");
88+
}
10189

102-
// Check that the values are synchronized
103-
for (int i = 0; i < client_handlers.Length; i++)
104-
{
105-
Assert.IsTrue(client_handlers[i].networksSerializableToSynchronize.IsSynchronizedWith(instantiationData), "Client handler " + i + " is not synchronized with server handler");
106-
}
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+
}
97+
98+
private void RegisterPrefab(NetworkManager manager, out PrefabInstanceHandlerWithData handler)
99+
{
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);
105+
}
106+
107+
private NetworkObject SpawnPrefabWithData(NetworkSerializableTest data)
108+
{
109+
var instance = GameObject.Instantiate(_prefab).GetComponent<NetworkObject>();
110+
instance.InjectInstantiationData(data);
111+
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);
122+
}
123+
124+
private IEnumerator WaitForAllClientsToSync(NetworkSerializableTest expectedData)
125+
{
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.");
107129
}
108130

109131
private class PrefabInstanceHandlerWithData : INetworkPrefabInstanceHandlerWithData<NetworkSerializableTest>
110132
{
111133
public GameObject Prefab;
112-
public NetworkSerializableTest networksSerializableToSynchronize;
134+
public NetworkSerializableTest instantiationData;
135+
113136
public PrefabInstanceHandlerWithData(GameObject prefab)
114137
{
115138
Prefab = prefab;
116139
}
140+
117141
public NetworkObject Instantiate(ulong ownerClientId, Vector3 position, Quaternion rotation, NetworkSerializableTest data)
118142
{
119-
Debug.Log($"Instantiating {Prefab.name} with data: {data.Value}, {data.Value2}");
120-
networksSerializableToSynchronize = data;
121-
var instance = GameObject.Instantiate(Prefab, position, rotation).GetComponent<NetworkObject>();
122-
return instance;
143+
instantiationData = data;
144+
return GameObject.Instantiate(Prefab, position, rotation).GetComponent<NetworkObject>();
123145
}
124146

125147
public void Destroy(NetworkObject networkObject)
126148
{
127149
GameObject.DestroyImmediate(networkObject.gameObject);
128150
}
129-
130151
}
131152

132-
struct NetworkSerializableTest : INetworkSerializable
153+
private struct NetworkSerializableTest : INetworkSerializable
133154
{
134155
public int Value;
135156
public float Value2;
157+
136158
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
137159
{
138160
serializer.SerializeValue(ref Value);
139161
serializer.SerializeValue(ref Value2);
140162
}
141163

142164
public bool IsSynchronizedWith(NetworkSerializableTest other)
143-
{
144-
bool isSynchronized = true;
145-
isSynchronized &= Value == other.Value;
146-
isSynchronized &= Value2 == other.Value2;
147-
return isSynchronized;
148-
}
165+
=> Value == other.Value && Math.Abs(Value2 - other.Value2) < 0.0001f;
149166
}
150167
}
151168
}

0 commit comments

Comments
 (0)