using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; namespace Mirror { /// /// Component that controls visibility of networked objects between scenes. /// Any object with this component on it will only be visible to other objects in the same scene /// This would be used when the server has multiple additive subscenes loaded to isolate players to their respective subscenes /// // Deprecated 2021-10-30 [DisallowMultipleComponent] [Obsolete("This component has been deprecated. Remove this component and add Scene Interest Management component to the same object as your Network Manager.")] public class NetworkSceneChecker : NetworkVisibility { /// /// Flag to force this object to be hidden from all observers. /// If this object is a player object, it will not be hidden for that client. /// [Tooltip("Enable to force this object to be hidden from all observers.")] public bool forceHidden; // Use Scene instead of string scene.name because when additively loading multiples of a subscene the name won't be unique static readonly Dictionary> sceneCheckerObjects = new Dictionary>(); Scene currentScene; [ServerCallback] void Awake() { currentScene = gameObject.scene; // Debug.Log($"NetworkSceneChecker.Awake currentScene: {currentScene}"); } public override void OnStartServer() { if (!sceneCheckerObjects.ContainsKey(currentScene)) sceneCheckerObjects.Add(currentScene, new HashSet()); sceneCheckerObjects[currentScene].Add(netIdentity); } public override void OnStopServer() { if (sceneCheckerObjects.ContainsKey(currentScene) && sceneCheckerObjects[currentScene].Remove(netIdentity)) RebuildSceneObservers(); } [ServerCallback] void Update() { if (currentScene == gameObject.scene) return; // This object is in a new scene so observers in the prior scene // and the new scene need to rebuild their respective observers lists. // Remove this object from the hashset of the scene it just left sceneCheckerObjects[currentScene].Remove(netIdentity); // RebuildObservers of all NetworkIdentity's in the scene this object just left RebuildSceneObservers(); // Set this to the new scene this object just entered currentScene = gameObject.scene; // Make sure this new scene is in the dictionary if (!sceneCheckerObjects.ContainsKey(currentScene)) sceneCheckerObjects.Add(currentScene, new HashSet()); // Add this object to the hashset of the new scene sceneCheckerObjects[currentScene].Add(netIdentity); // RebuildObservers of all NetworkIdentity's in the scene this object just entered RebuildSceneObservers(); } void RebuildSceneObservers() { foreach (NetworkIdentity networkIdentity in sceneCheckerObjects[currentScene]) if (networkIdentity != null) networkIdentity.RebuildObservers(false); } /// /// Callback used by the visibility system to determine if an observer (player) can see this object. /// If this function returns true, the network connection will be added as an observer. /// /// Network connection of a player. /// True if the player can see this object. public override bool OnCheckObserver(NetworkConnection conn) { if (forceHidden) return false; return conn.identity.gameObject.scene == gameObject.scene; } /// /// Callback used by the visibility system to (re)construct the set of observers that can see this object. /// Implementations of this callback should add network connections of players that can see this object to the observers set. /// /// The new set of observers for this object. /// True if the set of observers is being built for the first time. public override void OnRebuildObservers(HashSet observers, bool initialize) { // If forceHidden then return without adding any observers. if (forceHidden) return; // Add everything in the hashset for this object's current scene foreach (NetworkIdentity networkIdentity in sceneCheckerObjects[currentScene]) if (networkIdentity != null && networkIdentity.connectionToClient != null) observers.Add(networkIdentity.connectionToClient); } } }