diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs index 4c42f83a30..b0f94f7e19 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs @@ -1535,7 +1535,8 @@ internal NetworkSceneHandle GetSceneOriginHandle() /// or
/// /// The targeted client - public void NetworkShow(ulong clientId) + /// Whether to check object visibility before showing. Requires to be set. + public void NetworkShow(ulong clientId, bool checkVisibility = true) { if (!IsSpawned) { @@ -1575,9 +1576,9 @@ public void NetworkShow(ulong clientId) return; } - if (CheckObjectVisibility != null && !CheckObjectVisibility(clientId)) + if (checkVisibility && CheckObjectVisibility != null && !CheckObjectVisibility(clientId)) { - if (NetworkManagerOwner.LogLevel <= LogLevel.Normal) + if (NetworkManagerOwner.LogLevel <= LogLevel.Developer) { NetworkLog.LogWarning($"[NetworkShow] Trying to make {nameof(NetworkObject)} {name} visible to client ({clientId}) but {nameof(CheckObjectVisibility)} returned false!"); } @@ -1603,7 +1604,8 @@ public void NetworkShow(ulong clientId) /// /// The objects to become "netcode visible" to the targeted client /// The targeted client - public static void NetworkShow(List networkObjects, ulong clientId) + /// Whether to check object visibility before showing. Requires to be set. + public static void NetworkShow(List networkObjects, ulong clientId, bool checkVisibility = true) { if (networkObjects == null || networkObjects.Count == 0) { @@ -1612,7 +1614,7 @@ public static void NetworkShow(List networkObjects, ulong clientI } foreach (var networkObject in networkObjects) { - networkObject.NetworkShow(clientId); + networkObject.NetworkShow(clientId, checkVisibility); } } @@ -1630,7 +1632,8 @@ public static void NetworkShow(List networkObjects, ulong clientI /// or
/// /// The targeted client - public void NetworkHide(ulong clientId) + /// Whether to check object visibility before hiding. Requires to be set. + public void NetworkHide(ulong clientId, bool checkVisibility = true) { if (!IsSpawned) { @@ -1661,58 +1664,71 @@ public void NetworkHide(ulong clientId) } } - if (!NetworkManagerOwner.SpawnManager.RemoveObjectFromShowingTo(this, clientId)) + // If an object was marked for showing to a client, but not yet sent, we can just remove it from the list and not send a destroy message + if (NetworkManagerOwner.SpawnManager.RemoveObjectFromShowingTo(this, clientId)) + { + return; + } + + // If the check visibility is enabled and the CheckObjectVisibility delegate is not null and returns true, log a warning and return + if (checkVisibility && CheckObjectVisibility != null && CheckObjectVisibility(clientId)) { - if (!Observers.Contains(clientId)) + if (NetworkManagerOwner.LogLevel <= LogLevel.Developer) { - if (NetworkManagerOwner.LogLevel <= LogLevel.Developer) - { - NetworkLog.LogWarning($"[{name}] {nameof(NetworkObject)} already hidden from Client-{clientId}! (ignoring)"); - } - return; + NetworkLog.LogWarning($"[NetworkShow] Trying to hide {nameof(NetworkObject)} {name} from client ({clientId}) but {nameof(CheckObjectVisibility)} returned true!"); } - Observers.Remove(clientId); + return; + } - var message = new DestroyObjectMessage + if (!Observers.Contains(clientId)) + { + if (NetworkManagerOwner.LogLevel <= LogLevel.Developer) { - NetworkObjectId = NetworkObjectId, - DestroyGameObject = !InScenePlaced, - IsDistributedAuthority = NetworkManagerOwner.DistributedAuthorityMode, - IsTargetedDestroy = NetworkManagerOwner.DistributedAuthorityMode, - TargetClientId = clientId, // Just always populate this value whether we write it or not - DeferredDespawnTick = DeferredDespawnTick, - }; + NetworkLog.LogWarning($"[{name}] {nameof(NetworkObject)} already hidden from Client-{clientId}! (ignoring)"); + } + return; + } + Observers.Remove(clientId); - var size = 0; - if (NetworkManagerOwner.DistributedAuthorityMode) + var message = new DestroyObjectMessage + { + NetworkObjectId = NetworkObjectId, + DestroyGameObject = !InScenePlaced, + IsDistributedAuthority = NetworkManagerOwner.DistributedAuthorityMode, + IsTargetedDestroy = NetworkManagerOwner.DistributedAuthorityMode, + TargetClientId = clientId, // Just always populate this value whether we write it or not + DeferredDespawnTick = DeferredDespawnTick, + }; + + var size = 0; + if (NetworkManagerOwner.DistributedAuthorityMode) + { + if (!NetworkManagerOwner.DAHost) { - if (!NetworkManagerOwner.DAHost) - { - // Send destroy call to service or DAHost - size = NetworkManagerOwner.ConnectionManager.SendMessage(ref message, MessageDeliveryType.DefaultDelivery, NetworkManager.ServerClientId); - } - else // DAHost mocking service - { - // Send destroy call - size = NetworkManagerOwner.ConnectionManager.SendMessage(ref message, MessageDeliveryType.DefaultDelivery, clientId); - // Broadcast the destroy to all clients so they can update their observers list - foreach (var client in NetworkManagerOwner.ConnectionManager.ConnectedClientIds) - { - if (client == clientId || client == NetworkManagerOwner.LocalClientId) - { - continue; - } - size += NetworkManagerOwner.ConnectionManager.SendMessage(ref message, MessageDeliveryType.DefaultDelivery, client); - } - } + // Send destroy call to service or DAHost + size = NetworkManagerOwner.ConnectionManager.SendMessage(ref message, MessageDeliveryType.DefaultDelivery, NetworkManager.ServerClientId); } - else + else // DAHost mocking service { // Send destroy call size = NetworkManagerOwner.ConnectionManager.SendMessage(ref message, MessageDeliveryType.DefaultDelivery, clientId); + // Broadcast the destroy to all clients so they can update their observers list + foreach (var client in NetworkManagerOwner.ConnectionManager.ConnectedClientIds) + { + if (client == clientId || client == NetworkManagerOwner.LocalClientId) + { + continue; + } + size += NetworkManagerOwner.ConnectionManager.SendMessage(ref message, MessageDeliveryType.DefaultDelivery, client); + } } - NetworkManagerOwner.NetworkMetrics.TrackObjectDestroySent(clientId, this, size); } + else + { + // Send destroy call + size = NetworkManagerOwner.ConnectionManager.SendMessage(ref message, MessageDeliveryType.DefaultDelivery, clientId); + } + NetworkManagerOwner.NetworkMetrics.TrackObjectDestroySent(clientId, this, size); } /// @@ -1730,7 +1746,8 @@ public void NetworkHide(ulong clientId) /// /// The s that will become "netcode invisible" to the targeted client /// The targeted client - public static void NetworkHide(List networkObjects, ulong clientId) + /// Whether to check object visibility before hiding + public static void NetworkHide(List networkObjects, ulong clientId, bool checkVisibility = true) { if (networkObjects == null || networkObjects.Count == 0) { @@ -1739,7 +1756,7 @@ public static void NetworkHide(List networkObjects, ulong clientI } foreach (var networkObject in networkObjects) { - networkObject.NetworkHide(clientId); + networkObject.NetworkHide(clientId, checkVisibility); } }