diff --git a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs index 5cba446a1e..5336d7f76e 100644 --- a/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs +++ b/com.unity.netcode.gameobjects/Runtime/Spawning/NetworkSpawnManager.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; +using Unity.Collections; using UnityEngine; namespace Unity.Netcode @@ -577,12 +578,30 @@ internal void ChangeOwnership(NetworkObject networkObject, ulong clientId, bool // If we are connected to the CMB service or not the DAHost (i.e. pure DA-Clients only) if (NetworkManager.CMBServiceConnection || !NetworkManager.DAHost) { - // Populate valid target client identifiers that should receive this change in ownership message. - message.ClientIds = NetworkManager.ConnectedClientsIds.Where((c) => !IsObjectVisibilityPending(c, ref networkObject) && networkObject.IsNetworkVisibleTo(c)).ToArray(); - message.ClientIdCount = message.ClientIds.Length; + // Calculate valid target client identifiers that should receive this change in ownership message. + var clientIds = new List(NetworkManager.ConnectedClientsIds.Count); + foreach (var id in NetworkManager.ConnectedClientsIds) + { + if (id == NetworkManager.LocalClientId) + { + continue; + } - size = NetworkManager.ConnectionManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, NetworkManager.ServerClientId); - NetworkManager.NetworkMetrics.TrackOwnershipChangeSent(NetworkManager.LocalClientId, networkObject, size); + if (networkObject.IsNetworkVisibleTo(id) && !IsObjectVisibilityPending(id, ref networkObject)) + { + clientIds.Add(id); + } + } + + // Don't send the message if there are no valid receivers + if (clientIds.Count > 0) + { + message.ClientIds = clientIds.ToArray(); + message.ClientIdCount = clientIds.Count; + + size = NetworkManager.ConnectionManager.SendMessage(ref message, NetworkDelivery.ReliableSequenced, NetworkManager.ServerClientId); + NetworkManager.NetworkMetrics.TrackOwnershipChangeSent(NetworkManager.LocalClientId, networkObject, size); + } } else // We are the DAHost so broadcast the ownership change { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs index d4cf1d1f8a..c228c4cb33 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/DistributedAuthority/OwnershipPermissionsTests.cs @@ -17,12 +17,6 @@ internal class OwnershipPermissionsTests : IntegrationTestWithApproximation protected override int NumberOfClients => 4; - // TODO: [CmbServiceTests] Remove this once MTTB-1570 is resolved. - protected override bool UseCMBService() - { - return false; - } - public OwnershipPermissionsTests() : base(HostOrServer.DAHost) { } @@ -454,7 +448,7 @@ private IEnumerator ValidateRequestAndPermissionsChangeRaceCondition(NetworkObje } - // We expect the request should be able to be sent at this time as well (i.e. creates the race condition between request and permissions change) + // We expect the request should be able to be sent at this time as well (i.e. creates the race condition between request and permissions change) Assert.True(requestStatus == NetworkObject.OwnershipRequestStatus.RequestSent, $"[{newStatus}] Client-{firstClient.LocalClientId} was unable to send a request for ownership because: {requestStatus}!"); yield return WaitForConditionOrTimeOut(() => secondInstanceHelper.OwnershipRequestResponseStatus == expectedResponseStatus);