com.unity.netcode.gameobjects icon indicating copy to clipboard operation
com.unity.netcode.gameobjects copied to clipboard

CheckObjectVisibility Delegates Issues

Open CosmicStud opened this issue 3 years ago • 14 comments

Describe the bug Currently in the develop branch, CheckObject Visibility delegates are not applied. All network objects regardless of delegates are spawned on clients.

To Reproduce Start a server and spawn an object with checkObjectVisibility returning false Start client

Actual outcome Client visibly sees spawned object

Expected outcome Client does not see spawned object

Environment (please complete the following information):

  • OS: Mac OS
  • Unity Version:2021.2.7
  • Netcode Version: 1.1 develop, Dec 27

CosmicStud avatar Jan 02 '22 05:01 CosmicStud

Linking a Forum thread with some more information.

LukeStampfli avatar Jan 05 '22 16:01 LukeStampfli

Latest release 1.0.0-pre.4 does not fix the issue

CosmicStud avatar Jan 20 '22 17:01 CosmicStud

I upgraded to 1.0.0-pre.4 and I am still having this issue.

SamTheBay avatar Jan 23 '22 21:01 SamTheBay

I upgraded to 1.0.0-pre.4 and I am still having this issue.

How have you implemented the delegate, where in the exection? I ask because I assign the delegate after setting the game object active and directly before spawning

networkedObject.CheckObjectVisibility = ((clientId) => false); networkedObject.Spawn();

CosmicStud avatar Jan 24 '22 09:01 CosmicStud

I am setting it there as well as in the awake function of the object to try and catch all the places...

    NetworkLevel level = Instantiate<NetworkLevel>(levelPrefab);
    ...
    level.NetworkObject.CheckObjectVisibility = level.IsVisible;
    level.NetworkObject.Spawn();

The is visible function just returns false, but the level still shows up on the client.

SamTheBay avatar Jan 24 '22 19:01 SamTheBay

Tried #1588 fix, but it does not work for me.

MrCool92 avatar Jan 25 '22 08:01 MrCool92

I am setting it there as well as in the awake function of the object to try and catch all the places...

    NetworkLevel level = Instantiate<NetworkLevel>(levelPrefab);
    ...
    level.NetworkObject.CheckObjectVisibility = level.IsVisible;
    level.NetworkObject.Spawn();

The is visible function just returns false, but the level still shows up on the client.

Upon more inspection, seems the visibility is not fixed, strangely I had results which showed the issue fixed, its beyond me at this point

CosmicStud avatar Jan 26 '22 17:01 CosmicStud

The issues seems to be here:

image

The "else" part of the outer If statement, where the CheckVisibility happens, is never executed on the server because of the "|| NetworkManager.IsServer".

rCarleon avatar Jan 27 '22 13:01 rCarleon

The issues seems to be here:

image

The "else" part of the outer If statement, where the CheckVisibility happens, is never executed on the server because of the "|| NetworkManager.IsServer".

I can't reproduce, objects still visible, your fix works for you?

CosmicStud avatar Jan 27 '22 16:01 CosmicStud

The same issue was mentioned here #1306 back in October. It's marked as critical but strangely still open.

ezoray avatar Jan 27 '22 19:01 ezoray

The issues seems to be here: image The "else" part of the outer If statement, where the CheckVisibility happens, is never executed on the server because of the "|| NetworkManager.IsServer".

I can't reproduce, objects still visible, your fix works for you?

I meant the issue is somewhere in this part of the code (Screenshot). I did not try out anything, but if I had, the first thing I would do is to add to one of the "if"s the check for the visibility. Probably after the null check.

rCarleon avatar Jan 28 '22 10:01 rCarleon

Ya, this looks obviously wrong. I don't have time to learn how to download the project and create a proper pull request. However, I think this is likely the fix...

    internal void UpdateObservedNetworkObjects(ulong clientId)
    {
        foreach (var sobj in SpawnedObjectsList)
        {
            if (sobj.CheckObjectVisibility == null)
            {
                if (!sobj.Observers.Contains(clientId))
                {
                    sobj.Observers.Add(clientId);
                }
            }
            else
            {
                if (clientId == NetworkManager.ServerClientId || sobj.CheckObjectVisibility(clientId))
                {
                    sobj.Observers.Add(clientId);
                }
                else if (sobj.Observers.Contains(clientId))
                {
                    sobj.Observers.Remove(clientId);
                }
            }
        }
    }

SamTheBay avatar Jan 29 '22 18:01 SamTheBay

Ya, this looks obviously wrong. I don't have time to learn how to download the project and create a proper pull request. However, I think this is likely the fix...

    internal void UpdateObservedNetworkObjects(ulong clientId)
    {
        foreach (var sobj in SpawnedObjectsList)
        {
            if (sobj.CheckObjectVisibility == null)
            {
                if (!sobj.Observers.Contains(clientId))
                {
                    sobj.Observers.Add(clientId);
                }
            }
            else
            {
                if (clientId == NetworkManager.ServerClientId || sobj.CheckObjectVisibility(clientId))
                {
                    sobj.Observers.Add(clientId);
                }
                else if (sobj.Observers.Contains(clientId))
                {
                    sobj.Observers.Remove(clientId);
                }
            }
        }
    }

Fixed this issue in my project by implementing the changes from @SamTheBay and the following changes:

image

image

Maybe this is going to help someone.

rCarleon avatar Feb 05 '22 13:02 rCarleon

Tracked in our backlog MTT-3046

ashwinimurt avatar Mar 29 '22 21:03 ashwinimurt

I am pretty confident this was fixed in 1.0.0-pre.5, fix was in PR #1680. I'm closing this issue; if anyone still has this problem, let us know and we can re-open.

ShadauxCat avatar Aug 24 '22 22:08 ShadauxCat