Skip to content
107 changes: 86 additions & 21 deletions com.unity.netcode.gameobjects/Runtime/Core/NetworkObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1458,7 +1458,10 @@ internal NetworkSceneHandle GetSceneOriginHandle()
{
if (SceneOriginHandle.IsEmpty() && IsSpawned && IsSceneObject != false)
{
throw new Exception($"{nameof(GetSceneOriginHandle)} called when {nameof(SceneOriginHandle)} is still zero but the {nameof(NetworkObject)} is already spawned!");
if (NetworkManager.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"{nameof(GetSceneOriginHandle)} called when {nameof(SceneOriginHandle)} is still zero but the {nameof(NetworkObject)} is already spawned!");
}
}
return !SceneOriginHandle.IsEmpty() ? SceneOriginHandle : gameObject.scene.handle;
}
Expand All @@ -1481,31 +1484,50 @@ public void NetworkShow(ulong clientId)
{
if (!IsSpawned)
{
throw new SpawnStateException("Object is not spawned");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"[{name}] Attempted NetworkShow while not spawned.");
}
return;
}

if (!HasAuthority)
{
if (NetworkManagerOwner.DistributedAuthorityMode)
{
throw new NotServerException($"Only the owner-authority can change visibility when distributed authority mode is enabled!");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] Only the owner-authority can change visibility when distributed authority mode is enabled!");
}
return;
}
else
{
throw new NotServerException("Only the authority can change visibility");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] Only the authority can change visibility.");
}
return;
}
}

if (Observers.Contains(clientId))
{
if (NetworkManagerOwner.DistributedAuthorityMode)
{
Debug.LogError($"The object {name} is already visible to Client-{clientId}!");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"The object {name} is already visible to Client-{clientId}!");
}
return;
}
else
{
throw new NotServerException("Only server can change visibility");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] Only the server can change visibility.");
}
return;
}
}

Expand Down Expand Up @@ -1568,18 +1590,30 @@ public void NetworkHide(ulong clientId)
{
if (!IsSpawned)
{
throw new SpawnStateException("Object is not spawned");
if (NetworkManager.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"[{name}] Attempted NetworkHide while {nameof(NetworkObject)} is not spawned.");
}
return;
}

if (!HasAuthority && !NetworkManagerOwner.DAHost)
{
if (NetworkManagerOwner.DistributedAuthorityMode)
{
throw new NotServerException($"Only the owner-authority can change visibility when distributed authority mode is enabled!");
if (NetworkManager.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] Only the owner-authority can change visibility when distributed authority mode is enabled!");
}
return;
}
else
{
throw new NotServerException("Only the authority can change visibility");
if (NetworkManager.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] Only the authority can change visibility!");
}
return;
}
}

Expand All @@ -1589,9 +1623,9 @@ public void NetworkHide(ulong clientId)
{
if (NetworkManagerOwner.LogLevel <= LogLevel.Developer)
{
Debug.LogWarning($"{name} is already hidden from Client-{clientId}! (ignoring)");
return;
NetworkLog.LogWarning($"[{name}] {nameof(NetworkObject)} already hidden from Client-{clientId}! (ignoring)");
}
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be great to have a test on this case, maybe one where an object is hidden from a client twice and then shown to that client twice so we can check the behaviour is symmetrical as well?

}
Observers.Remove(clientId);

Expand Down Expand Up @@ -1724,18 +1758,30 @@ internal void SpawnInternal(bool destroyWithScene, ulong ownerClientId, bool pla

if (!NetworkManagerOwner.IsListening)
{
throw new NotListeningException($"{nameof(NetworkManagerOwner)} is not listening, start a server or host before spawning objects");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] {nameof(NetworkManagerOwner)} is not listening, start a server or host before spawning objects.");
}
return;
}

if ((!NetworkManagerOwner.IsServer && !NetworkManagerOwner.DistributedAuthorityMode) || (NetworkManagerOwner.DistributedAuthorityMode && !NetworkManagerOwner.LocalClient.IsSessionOwner && NetworkManagerOwner.LocalClientId != ownerClientId))
{
if (NetworkManagerOwner.DistributedAuthorityMode)
{
throw new NotServerException($"When distributed authority mode is enabled, you can only spawn NetworkObjects that belong to the local instance! Local instance id {NetworkManagerOwner.LocalClientId} is not the same as the assigned owner id: {ownerClientId}!");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] When distributed authority mode is enabled, you can only spawn NetworkObjects that belong to the local instance! Local instance id {NetworkManagerOwner.LocalClientId} is not the same as the assigned owner id: {ownerClientId}!");
}
return;
}
else
{
throw new NotServerException($"Only server can spawn {nameof(NetworkObject)}s");
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] Only server can spawn {nameof(NetworkObject)}s.");
}
return;
}
}

Expand Down Expand Up @@ -2256,7 +2302,10 @@ private void OnTransformParentChanged()
return;
}
transform.parent = m_CachedParent;
Debug.LogException(new NotListeningException($"[{name}] {nameof(networkManager)} is not listening, start a server or host before re-parenting"));
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogError($"[{name}] {nameof(networkManager)} is not listening, start a server or host before re-parenting.");
}
return;
}

Expand All @@ -2273,7 +2322,10 @@ private void OnTransformParentChanged()
else
{
transform.parent = m_CachedParent;
Debug.LogException(new SpawnStateException($"[{name}] {nameof(NetworkObject)} can only be re-parented after being spawned"));
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"[{name}] {nameof(NetworkObject)} can only be re-parented after being spawned!");
}
}
return;
}
Expand All @@ -2293,7 +2345,7 @@ private void OnTransformParentChanged()
}
else
{
Debug.LogException(new NotServerException($"[{name}] Only the server can re-parent {nameof(NetworkObject)}s"));
NetworkLog.LogError($"[{name}] Only the server can re-parent {nameof(NetworkObject)}s.");
}
}
return;
Expand All @@ -2307,14 +2359,20 @@ private void OnTransformParentChanged()
{
transform.parent = m_CachedParent;
AuthorityAppliedParenting = false;
Debug.LogException(new InvalidParentException($"[{name}] Invalid parenting, {nameof(NetworkObject)} moved under a non-{nameof(NetworkObject)} parent"));
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"[{name}] Invalid parenting, {nameof(NetworkObject)} moved under a non-{nameof(NetworkObject)} parent");
}
return;
}
else if (!parentObject.IsSpawned)
{
transform.parent = m_CachedParent;
AuthorityAppliedParenting = false;
Debug.LogException(new SpawnStateException($"[{name}] {nameof(NetworkObject)} can only be re-parented under another spawned {nameof(NetworkObject)}"));
if (NetworkManagerOwner.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"[{name}] {nameof(NetworkObject)} can only be re-parented under another spawned {nameof(NetworkObject)}.");
}
return;
}

Expand Down Expand Up @@ -2536,7 +2594,10 @@ internal void InvokeBehaviourNetworkSpawn()
{
if (!childBehaviour.gameObject.activeInHierarchy)
{
Debug.LogWarning($"{GenerateDisabledNetworkBehaviourWarning(childBehaviour)}");
if (NetworkManagerOwner.LogLevel <= LogLevel.Developer)
{
NetworkLog.LogWarning($"{GenerateDisabledNetworkBehaviourWarning(childBehaviour)}");
}
continue;
}
childBehaviour.InternalOnNetworkSpawn();
Expand Down Expand Up @@ -3327,7 +3388,11 @@ internal static NetworkObject Deserialize(in SerializedObject serializedObject,
// Spawn the NetworkObject
if (networkObject.IsSpawned)
{
throw new SpawnStateException($"[{networkObject.name}] Object-{networkObject.NetworkObjectId} is already spawned!");
if (NetworkManager.Singleton.LogLevel <= LogLevel.Error)
{
NetworkLog.LogErrorServer($"[{networkObject.name}] Object-{networkObject.NetworkObjectId} is already spawned!");
}
return null;
}

// Invoke the non-authority local spawn method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Unity.Netcode
/// <summary>
/// Exception thrown when the operation require NetworkManager to be listening.
/// </summary>
[Obsolete("Not used anymore.")]
public class NotListeningException : Exception
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ public void SetupSet(Transform rootTransform, int setIndex, NetworkManager netwo
Assert.That(m_Pickup_NetObjs[setIndex], Is.Not.Null);
Assert.That(m_Pickup_Back_NetObjs[setIndex], Is.Not.Null);

LogAssert.Expect(LogType.Exception, new Regex("start a server or host", RegexOptions.IgnoreCase));
LogAssert.Expect(LogType.Error, new Regex("start a server or host", RegexOptions.IgnoreCase));
var cachedParent = m_Cube_NetObjs[setIndex].parent;
m_Cube_NetObjs[setIndex].parent = m_Pickup_NetObjs[setIndex];
Assert.That(m_Cube_NetObjs[setIndex].parent, Is.EqualTo(cachedParent), $"Transform {m_Cube_NetObjs[setIndex].parent.name} is not equal to transform {cachedParent.name}");
Expand Down