To set custom visibility in UNet you must create a class that manipulates the "observers" list for the NetworkIdentity Component of a GameObject. But the problems is that it's oriented towards the non-players instead of the actual players e.g: If you have 30 enemies on the map that must be synchronized to 2 players, then you will have to call RebuildObservers for all of these 30 enemies and during the OnRebuildObservers event that occurs on each enemy you have to add those 2 players NetworkConnection to its "observers" list. The way it should be done is to have a list of relevant NetworkIdentity inside of the NetworkIdentity class instead of the current "observers" list. So we would only have to maintain the lists for those 2 players. The current implementation: Code (csharp): public sealed class NetworkIdentity : MonoBehaviour { ...STUFF... public ReadOnlyCollection<NetworkConnection> observers { get; } ...STUFF... public void RebuildObservers(bool initialize); } So this is like: Enemy1 observers list ------Player1 ------Player2 Enemy2 observers list ------Player1 ------Player2 Enemy3 observers list ------Player1 ------Player2 ... ... ... Enemy30 observers list ------Player1 ------Player2 Player1 observers list ------Player2 Player2 observers list ------Player1 How it should be implemented: Code (csharp): public sealed class NetworkIdentity : MonoBehaviour { ...STUFF... public ReadOnlyCollection<NetworkIdentity> relevantNetworkIdenties { get; } ...STUFF... public void RebuildRelevantNetworkIdenties(bool initialize); } So this would be like: Player1 relevantNetworkIdenties list ------Enemy1 ------Enemy2 ------Enemy3 ... ... ... ------Enemy30 ------Player2 Player2 relevantNetworkIdenties list ------Enemy1 ------Enemy2 ------Enemy3 ... ... ... ------Enemy30 ------Player1
When state changes for an object, a state update message is sent to the observers. Having the list of observers for the object be local and convenient makes sending updates to those observers fast. This is the most common operation, so the data layout is setup for that to be fast. If the data was per-connection, then to send a state update for an object, how does the system know which players to send the update to? It could iterate through the list of players, and check if the object is in the player's relevantNetworkIdentities list, but that could be slow if there are many players in the game - and wasteful if most of them cannot see the object.
You can iterate over each player's relevantNetworkIdentities (which store all NetworkIdentity that is relevant to this player) to check if the relevant object's state has changed and send the state update message to this player.