Skip to content

Commit 26b4f35

Browse files
authored
Merge branch 'develop' into fix/INetworkSerializable_in_NetworkList_develop
2 parents 8e8c476 + 8334e94 commit 26b4f35

File tree

10 files changed

+139
-14
lines changed

10 files changed

+139
-14
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ Additional documentation and release notes are available at [Multiplayer Documen
2323
- Fixed overloading RPC methods causing collisions and failing on IL2CPP targets. (#1694)
2424
- Fixed spawn flow to propagate `IsSceneObject` down to children NetworkObjects, decouple implicit relationship between object spawning & `IsSceneObject` flag (#1685)
2525
- Fixed NetworkList now properly calls INetworkSerializable's NetworkSerialize() method (#1682)
26+
- Fixed error when serializing ConnectionApprovalMessage with scene management disabled when one or more objects is hidden via the CheckObjectVisibility delegate (#1720)
27+
- Fixed CheckObjectVisibility delegate not being properly invoked for connecting clients when Scene Management is enabled. (#1680)
2628

2729
## [1.0.0-pre.5] - 2022-01-26
2830

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,6 @@ internal void HandleApproval(ulong ownerClientId, bool createPlayerObject, uint?
17061706
{
17071707
if (SpawnManager.SpawnedObjectsList.Count != 0)
17081708
{
1709-
message.SceneObjectCount = SpawnManager.SpawnedObjectsList.Count;
17101709
message.SpawnedObjectsList = SpawnManager.SpawnedObjectsList;
17111710
}
17121711
}

com.unity.netcode.gameobjects/Runtime/Messaging/Messages/ConnectionApprovedMessage.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ internal struct ConnectionApprovedMessage : INetworkMessage
77
{
88
public ulong OwnerClientId;
99
public int NetworkTick;
10-
public int SceneObjectCount;
1110

1211
// Not serialized, held as references to serialize NetworkVariable data
1312
public HashSet<NetworkObject> SpawnedObjectsList;
@@ -18,15 +17,17 @@ public void Serialize(FastBufferWriter writer)
1817
{
1918
if (!writer.TryBeginWrite(sizeof(ulong) + sizeof(int) + sizeof(int)))
2019
{
21-
throw new OverflowException(
22-
$"Not enough space in the write buffer to serialize {nameof(ConnectionApprovedMessage)}");
20+
throw new OverflowException($"Not enough space in the write buffer to serialize {nameof(ConnectionApprovedMessage)}");
2321
}
2422
writer.WriteValue(OwnerClientId);
2523
writer.WriteValue(NetworkTick);
26-
writer.WriteValue(SceneObjectCount);
2724

28-
if (SceneObjectCount != 0)
25+
uint sceneObjectCount = 0;
26+
if (SpawnedObjectsList != null)
2927
{
28+
var pos = writer.Position;
29+
writer.Seek(writer.Position + FastBufferWriter.GetWriteSize(sceneObjectCount));
30+
3031
// Serialize NetworkVariable data
3132
foreach (var sobj in SpawnedObjectsList)
3233
{
@@ -35,8 +36,16 @@ public void Serialize(FastBufferWriter writer)
3536
sobj.Observers.Add(OwnerClientId);
3637
var sceneObject = sobj.GetMessageSceneObject(OwnerClientId);
3738
sceneObject.Serialize(writer);
39+
++sceneObjectCount;
3840
}
3941
}
42+
writer.Seek(pos);
43+
writer.WriteValue(sceneObjectCount);
44+
writer.Seek(writer.Length);
45+
}
46+
else
47+
{
48+
writer.WriteValue(sceneObjectCount);
4049
}
4150
}
4251

@@ -50,13 +59,11 @@ public bool Deserialize(FastBufferReader reader, ref NetworkContext context)
5059

5160
if (!reader.TryBeginRead(sizeof(ulong) + sizeof(int) + sizeof(int)))
5261
{
53-
throw new OverflowException(
54-
$"Not enough space in the buffer to read {nameof(ConnectionApprovedMessage)}");
62+
throw new OverflowException($"Not enough space in the buffer to read {nameof(ConnectionApprovedMessage)}");
5563
}
5664

5765
reader.ReadValue(out OwnerClientId);
5866
reader.ReadValue(out NetworkTick);
59-
reader.ReadValue(out SceneObjectCount);
6067
m_ReceivedSceneObjectData = reader;
6168
return true;
6269
}
@@ -77,10 +84,11 @@ public void Handle(ref NetworkContext context)
7784
if (!networkManager.NetworkConfig.EnableSceneManagement)
7885
{
7986
networkManager.SpawnManager.DestroySceneObjects();
87+
m_ReceivedSceneObjectData.ReadValue(out uint sceneObjectCount);
8088

8189
// Deserializing NetworkVariable data is deferred from Receive() to Handle to avoid needing
8290
// to create a list to hold the data. This is a breach of convention for performance reasons.
83-
for (ushort i = 0; i < SceneObjectCount; i++)
91+
for (ushort i = 0; i < sceneObjectCount; i++)
8492
{
8593
var sceneObject = new NetworkObject.SceneObject();
8694
sceneObject.Deserialize(m_ReceivedSceneObjectData);

com.unity.netcode.gameobjects/Runtime/SceneManagement/SceneEventData.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,14 @@ internal void InitializeForSynch()
233233

234234
internal void AddSpawnedNetworkObjects()
235235
{
236-
m_NetworkObjectsSync = m_NetworkManager.SpawnManager.SpawnedObjectsList.ToList();
236+
m_NetworkObjectsSync.Clear();
237+
foreach (var sobj in m_NetworkManager.SpawnManager.SpawnedObjectsList)
238+
{
239+
if (sobj.Observers.Contains(TargetClientId))
240+
{
241+
m_NetworkObjectsSync.Add(sobj);
242+
}
243+
}
237244
m_NetworkObjectsSync.Sort(SortNetworkObjects);
238245
}
239246

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ internal void UpdateObservedNetworkObjects(ulong clientId)
835835
{
836836
foreach (var sobj in SpawnedObjectsList)
837837
{
838-
if (sobj.CheckObjectVisibility == null || NetworkManager.IsServer)
838+
if (sobj.CheckObjectVisibility == null)
839839
{
840840
if (!sobj.Observers.Contains(clientId))
841841
{
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Unity.Netcode.RuntimeTests
2+
{
3+
public class NetworkVisibilityComponent : NetworkBehaviour
4+
{
5+
public void Hide()
6+
{
7+
GetComponent<NetworkObject>().CheckObjectVisibility += HandleCheckObjectVisibility;
8+
}
9+
10+
protected virtual bool HandleCheckObjectVisibility(ulong clientId) => false;
11+
12+
}
13+
}

com.unity.netcode.gameobjects/Tests/Runtime/Components/NetworkVisibilityComponent.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.netcode.gameobjects/Tests/Runtime/MultiInstanceHelpers.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,15 +263,17 @@ private static void SceneManagerValidationAndTestRunnerInitialization(NetworkMan
263263
}
264264
}
265265

266+
public delegate void BeforeClientStartCallback();
267+
266268
/// <summary>
267269
/// Starts NetworkManager instances created by the Create method.
268270
/// </summary>
269271
/// <param name="host">Whether or not to create a Host instead of Server</param>
270272
/// <param name="server">The Server NetworkManager</param>
271273
/// <param name="clients">The Clients NetworkManager</param>
272-
/// <param name="startInitializationCallback">called immediately after server and client(s) are started</param>
274+
/// <param name="callback">called immediately after server is started and before client(s) are started</param>
273275
/// <returns></returns>
274-
public static bool Start(bool host, NetworkManager server, NetworkManager[] clients)
276+
public static bool Start(bool host, NetworkManager server, NetworkManager[] clients, BeforeClientStartCallback callback = null)
275277
{
276278
if (s_IsStarted)
277279
{
@@ -293,6 +295,8 @@ public static bool Start(bool host, NetworkManager server, NetworkManager[] clie
293295
// if set, then invoke this for the server
294296
RegisterHandlers(server);
295297

298+
callback?.Invoke();
299+
296300
for (int i = 0; i < clients.Length; i++)
297301
{
298302
clients[i].StartClient();
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System.Collections;
2+
using NUnit.Framework;
3+
using UnityEngine;
4+
using UnityEngine.TestTools;
5+
6+
namespace Unity.Netcode.RuntimeTests
7+
{
8+
public class NetworkVisibilityTests
9+
{
10+
private NetworkObject m_NetSpawnedObject;
11+
private GameObject m_TestNetworkPrefab;
12+
13+
[TearDown]
14+
public void TearDown()
15+
{
16+
MultiInstanceHelpers.Destroy();
17+
if (m_TestNetworkPrefab)
18+
{
19+
Object.Destroy(m_TestNetworkPrefab);
20+
m_TestNetworkPrefab = null;
21+
}
22+
}
23+
24+
[UnityTest]
25+
public IEnumerator HiddenObjectsTest([Values] bool enableSeneManagement)
26+
{
27+
28+
const int numClients = 1;
29+
Assert.True(MultiInstanceHelpers.Create(numClients, out NetworkManager server, out NetworkManager[] clients));
30+
m_TestNetworkPrefab = new GameObject("Object");
31+
var networkObject = m_TestNetworkPrefab.AddComponent<NetworkObject>();
32+
m_TestNetworkPrefab.AddComponent<NetworkVisibilityComponent>();
33+
34+
// Make it a prefab
35+
MultiInstanceHelpers.MakeNetworkObjectTestPrefab(networkObject);
36+
37+
var validNetworkPrefab = new NetworkPrefab();
38+
validNetworkPrefab.Prefab = m_TestNetworkPrefab;
39+
server.NetworkConfig.NetworkPrefabs.Add(validNetworkPrefab);
40+
server.NetworkConfig.EnableSceneManagement = enableSeneManagement;
41+
foreach (var client in clients)
42+
{
43+
client.NetworkConfig.NetworkPrefabs.Add(validNetworkPrefab);
44+
client.NetworkConfig.EnableSceneManagement = enableSeneManagement;
45+
}
46+
47+
// Start the instances
48+
if (!MultiInstanceHelpers.Start(true, server, clients, () =>
49+
{
50+
var serverObject = Object.Instantiate(m_TestNetworkPrefab, Vector3.zero, Quaternion.identity);
51+
NetworkObject serverNetworkObject = serverObject.GetComponent<NetworkObject>();
52+
serverNetworkObject.NetworkManagerOwner = server;
53+
serverNetworkObject.Spawn();
54+
serverObject.GetComponent<NetworkVisibilityComponent>().Hide();
55+
}))
56+
{
57+
Debug.LogError("Failed to start instances");
58+
Assert.Fail("Failed to start instances");
59+
}
60+
61+
// [Client-Side] Wait for a connection to the server
62+
yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.WaitForClientsConnected(clients, null, 512));
63+
64+
// [Host-Side] Check to make sure all clients are connected
65+
yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.WaitForClientsConnectedToServer(server, clients.Length + 1, null, 512));
66+
67+
Assert.AreEqual(2, Object.FindObjectsOfType<NetworkVisibilityComponent>().Length);
68+
}
69+
}
70+
}

com.unity.netcode.gameobjects/Tests/Runtime/NetworkVisibilityTests.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)