Skip to content

Commit dfe7138

Browse files
fix: NetworkClient.OwnedObjects always returning a count of zero (#2631)
* fix This fixes the issue with NetworkClient.OwnedObjects always returning a zero count. * style removing TODO 2023-Q2 comments * test This validates the fixes for the owned objects list. * update removing an unrequired change. * update Adding the change log entry for this PR. * test fix Only test host for spawned objects locally, ignore that one portion when testing server only pass.
1 parent 7e4efe1 commit dfe7138

File tree

8 files changed

+78
-21
lines changed

8 files changed

+78
-21
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Additional documentation and release notes are available at [Multiplayer Documen
1212

1313
### Fixed
1414

15+
- Fixed issue where `NetworkClient.OwnedObjects` was not returning any owned objects due to the `NetworkClient.IsConnected` not being properly set. (#2631)
1516
- Fixed a crash when calling TrySetParent with a null Transform (#2625)
1617
- Fixed issue where a `NetworkTransform` using full precision state updates was losing transform state updates when interpolation was enabled. (#2624)
1718
- Fixed issue where `NetworkObject.SpawnWithObservers` was not being honored for late joining clients. (#2623)

com.unity.netcode.gameobjects/Runtime/Connection/NetworkClient.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,11 @@ public class NetworkClient
3636
/// <summary>
3737
/// The ClientId of the NetworkClient
3838
/// </summary>
39-
// TODO-2023-Q2: Determine if we want to make this property a public get and internal/private set
40-
// There is no reason for a user to want to set this, but this will fail the package-validation-suite
4139
public ulong ClientId;
4240

4341
/// <summary>
4442
/// The PlayerObject of the Client
4543
/// </summary>
46-
// TODO-2023-Q2: Determine if we want to make this property a public get and internal/private set
47-
// There is no reason for a user to want to set this, but this will fail the package-validation-suite
4844
public NetworkObject PlayerObject;
4945

5046
/// <summary>

com.unity.netcode.gameobjects/Runtime/Connection/NetworkConnectionManager.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ namespace Unity.Netcode
1717
/// - Processing <see cref="NetworkEvent"/>s.
1818
/// - Client Disconnection
1919
/// </summary>
20-
// TODO 2023-Q2: Discuss what kind of public API exposure we want for this
2120
public sealed class NetworkConnectionManager
2221
{
2322
#if DEVELOPMENT_BUILD || UNITY_EDITOR
@@ -656,6 +655,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
656655
// If scene management is disabled, then we are done and notify the local host-server the client is connected
657656
if (!NetworkManager.NetworkConfig.EnableSceneManagement)
658657
{
658+
NetworkManager.ConnectedClients[ownerClientId].IsConnected = true;
659659
InvokeOnClientConnectedCallback(ownerClientId);
660660
}
661661
else // Otherwise, let NetworkSceneManager handle the initial scene and NetworkObject synchronization
@@ -667,6 +667,7 @@ internal void HandleConnectionApproval(ulong ownerClientId, NetworkManager.Conne
667667
{
668668
LocalClient = client;
669669
NetworkManager.SpawnManager.UpdateObservedNetworkObjects(ownerClientId);
670+
LocalClient.IsConnected = true;
670671
}
671672

672673
if (!response.CreatePlayerObject || (response.PlayerPrefabHash == null && NetworkManager.NetworkConfig.PlayerPrefab == null))
@@ -732,12 +733,10 @@ internal void ApprovedPlayerSpawn(ulong clientId, uint playerPrefabHash)
732733
internal NetworkClient AddClient(ulong clientId)
733734
{
734735
var networkClient = LocalClient;
735-
if (clientId != NetworkManager.ServerClientId)
736-
{
737-
networkClient = new NetworkClient();
738-
networkClient.SetRole(isServer: false, isClient: true, NetworkManager);
739-
networkClient.ClientId = clientId;
740-
}
736+
737+
networkClient = new NetworkClient();
738+
networkClient.SetRole(clientId == NetworkManager.ServerClientId, isClient: true, NetworkManager);
739+
networkClient.ClientId = clientId;
741740

742741
ConnectedClients.Add(clientId, networkClient);
743742
ConnectedClientsList.Add(networkClient);
@@ -800,8 +799,7 @@ internal void OnClientDisconnectFromServer(ulong clientId)
800799
}
801800
else
802801
{
803-
// Handle changing ownership and prefab handlers
804-
// TODO-2023: Look into whether in-scene placed NetworkObjects could be destroyed if ownership changes to a client
802+
// Handle changing ownership and prefab handlers
805803
for (int i = clientOwnedObjects.Count - 1; i >= 0; i--)
806804
{
807805
var ownedObject = clientOwnedObjects[i];

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ internal void Shutdown()
118118
m_NetworkManager.NetworkTickSystem.Tick -= NetworkBehaviourUpdater_Tick;
119119
}
120120

121-
// TODO 2023-Q2: Order of operations requires NetworkVariable updates first then showing NetworkObjects
121+
// Order of operations requires NetworkVariable updates first then showing NetworkObjects
122122
private void NetworkBehaviourUpdater_Tick()
123123
{
124124
// First update NetworkVariables

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,12 @@ public void NetworkUpdate(NetworkUpdateStage updateStage)
5959
// Metrics update needs to be driven by NetworkConnectionManager's update to assure metrics are dispatched after the send queue is processed.
6060
MetricsManager.UpdateMetrics();
6161

62-
// TODO 2023-Q2: Determine a better way to handle this
62+
// TODO: Determine a better way to handle this
6363
NetworkObject.VerifyParentingStatus();
6464

6565
// This is "ok" to invoke when not processing messages since it is just cleaning up messages that never got handled within their timeout period.
6666
DeferredMessageManager.CleanupStaleTriggers();
6767

68-
// TODO 2023-Q2: Determine a better way to handle this
6968
if (m_ShuttingDown)
7069
{
7170
ShutdownInternal();
@@ -834,9 +833,7 @@ public bool StartHost()
834833
}
835834

836835
ConnectionManager.LocalClient.SetRole(true, true, this);
837-
838836
Initialize(true);
839-
840837
try
841838
{
842839
IsListening = NetworkConfig.NetworkTransport.StartServer();

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,6 +2191,10 @@ private void HandleServerSceneEvent(uint sceneEventId, ulong clientId)
21912191
ClientId = clientId
21922192
});
21932193

2194+
// At this point the client is considered fully "connected"
2195+
NetworkManager.ConnectedClients[clientId].IsConnected = true;
2196+
2197+
// All scenes are synchronized, let the server know we are done synchronizing
21942198
OnSynchronizeComplete?.Invoke(clientId);
21952199

21962200
// At this time the client is fully synchronized with all loaded scenes and

com.unity.netcode.gameobjects/Runtime/Timing/NetworkTimeSystem.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ namespace Unity.Netcode
99
/// </summary>
1010
public class NetworkTimeSystem
1111
{
12-
/// <summary>
13-
/// TODO 2023-Q2: Not sure if this just needs to go away, but there is nothing that ever replaces this
14-
/// </summary>
1512
/// <remarks>
1613
/// This was the original comment when it lived in NetworkManager:
1714
/// todo talk with UX/Product, find good default value for this

com.unity.netcode.gameobjects/Tests/Runtime/NetworkObject/NetworkObjectOwnershipTests.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,5 +294,69 @@ bool WaitForClientsToSpawnNetworkObject()
294294
}
295295
serverComponent.ResetFlags();
296296
}
297+
298+
private const int k_NumberOfSpawnedObjects = 5;
299+
300+
private bool AllClientsHaveCorrectObjectCount()
301+
{
302+
303+
foreach (var clientNetworkManager in m_ClientNetworkManagers)
304+
{
305+
if (clientNetworkManager.LocalClient.OwnedObjects.Count < k_NumberOfSpawnedObjects)
306+
{
307+
return false;
308+
}
309+
}
310+
311+
return true;
312+
}
313+
314+
private bool ServerHasCorrectClientOwnedObjectCount()
315+
{
316+
// Only check when we are the host
317+
if (m_ServerNetworkManager.IsHost)
318+
{
319+
if (m_ServerNetworkManager.LocalClient.OwnedObjects.Count < k_NumberOfSpawnedObjects)
320+
{
321+
return false;
322+
}
323+
}
324+
325+
foreach (var connectedClient in m_ServerNetworkManager.ConnectedClients)
326+
{
327+
if (connectedClient.Value.OwnedObjects.Count < k_NumberOfSpawnedObjects)
328+
{
329+
return false;
330+
}
331+
}
332+
return true;
333+
}
334+
335+
[UnityTest]
336+
public IEnumerator TestOwnedObjectCounts()
337+
{
338+
if (m_ServerNetworkManager.IsHost)
339+
{
340+
for (int i = 0; i < 5; i++)
341+
{
342+
SpawnObject(m_OwnershipPrefab, m_ServerNetworkManager);
343+
}
344+
}
345+
346+
foreach (var clientNetworkManager in m_ClientNetworkManagers)
347+
{
348+
for (int i = 0; i < 5; i++)
349+
{
350+
SpawnObject(m_OwnershipPrefab, clientNetworkManager);
351+
}
352+
}
353+
354+
yield return WaitForConditionOrTimeOut(AllClientsHaveCorrectObjectCount);
355+
AssertOnTimeout($"Not all clients spawned {k_NumberOfSpawnedObjects} {nameof(NetworkObject)}s!");
356+
357+
yield return WaitForConditionOrTimeOut(ServerHasCorrectClientOwnedObjectCount);
358+
AssertOnTimeout($"Server does not have the correct count for all clients spawned {k_NumberOfSpawnedObjects} {nameof(NetworkObject)}s!");
359+
360+
}
297361
}
298362
}

0 commit comments

Comments
 (0)