NetworkShow and the CheckObjectVisibility Delegate
See original GitHub issueDescription
i think to fix several other issues in the NetworkList, a major feature was overlooked and removed. Currently if a “CheckObjectVisibility” delegate is set on a network object and returns false. Then a manual call with “NetworkShow” is made on the network object. No matter what it will never spawn on the client. I think this should be regressed. The developer should have full control over the objects visibility. This change removes developer choice.
Currently, all objects are set to hidden in my project. I would assume that would be the case for a good majority of devs. Or otherwise a lot of bandwidth will undoubtedly be used. If I ever wanted to show an objects visibility forcibly, I cannot anymore. Unless I create another set of workarounds. The only two options are lambda functions, which can be designed with more local data in the method. Or using a delegate, which only the ID of the client is usable…
Before NGO 1.4 release, this was not an issue. If possible can we design NGO to add a parameter to force the “NetworkShow” call and ignore the “CheckObjectVisibility”…
Reproduce Steps
- Assign “CheckObjectVisibility” delegate, return false.
- Spawn the network object.
- Show visibility of network object with “NetworkShow.”
Actual Outcome
A warning appears with method execution also ending before spawn implementation.
Expected Outcome
Visibility of network object is shown to client. Due to server having a call on the network object to show visibility.
Environment
- OS: Mac OS Catalina
- Unity Version: 2022.2.15
- Netcode Version: 1.4
- Netcode Commit: [e.g. https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/commit/ba418fa5b600ad9eb61fab0575f12fbecc2c6520]
Additional Context
Current “NetworkObject” class, starting line number 339
public void NetworkShow(ulong clientId)
{
if (!IsSpawned)
{
throw new SpawnStateException("Object is not spawned");
}
if (!NetworkManager.IsServer)
{
throw new NotServerException("Only server can change visibility");
}
if (Observers.Contains(clientId))
{
throw new VisibilityChangeException("The object is already visible");
}
if (CheckObjectVisibility != null && !CheckObjectVisibility(clientId))
{
if (NetworkManager.LogLevel <= LogLevel.Normal)
{
NetworkLog.LogWarning($"[NetworkShow] Trying to make {nameof(NetworkObject)} {gameObject.name} visible to client ({clientId}) but {nameof(CheckObjectVisibility)} returned false!");
}
return;
}
NetworkManager.SpawnManager.MarkObjectForShowingTo(this, clientId);
Observers.Add(clientId);
}
A possible fix for this would be…
public void NetworkShow(ulong clientId, bool isForced = false)
{
if (!IsSpawned)
{
throw new SpawnStateException("Object is not spawned");
}
if (!NetworkManager.IsServer)
{
throw new NotServerException("Only server can change visibility");
}
if (Observers.Contains(clientId))
{
throw new VisibilityChangeException("The object is already visible");
}
if (!isForced)
{
if (CheckObjectVisibility != null && !CheckObjectVisibility(clientId))
{
if (NetworkManager.LogLevel <= LogLevel.Normal)
{
NetworkLog.LogWarning($"[NetworkShow] Trying to make {nameof(NetworkObject)} {gameObject.name} visible to client ({clientId}) but {nameof(CheckObjectVisibility)} returned false!");
}
return;
}
}
NetworkManager.SpawnManager.MarkObjectForShowingTo(this, clientId);
Observers.Add(clientId);
}
Issue Analytics
- State:
- Created 5 months ago
- Reactions:1
- Comments:15 (6 by maintainers)
Top GitHub Comments
@CosmicStud @ezoray In the next update you will have a
NetworkObject.SpawnWithObservers
property (default is true) that you can set to false and it will spawn the NetworkObject with no observers. The only change you will have to make on your end is to remove the CheckObjectVisibility handler and just setNetworkObject.SpawnWithObservers
to false. 👍@NoelStephensUnity that addition is much appreciated thank you.