Description
Description
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);
}