using System; using System.Collections.Generic; using UnityEngine; namespace UnityEngine.Networking { /// /// Component that controls visibility of networked objects for players. /// Any object with this component on it will not be visible to players more than a (configurable) distance away. /// [AddComponentMenu("Network/NetworkProximityChecker")] [RequireComponent(typeof(NetworkIdentity))] [Obsolete("The high level API classes are deprecated and will be removed in the future.")] public class NetworkProximityChecker : NetworkBehaviour { /// /// Enumeration of methods to use to check proximity. /// public enum CheckMethod { /// /// Use 3D physics to determine proximity. /// Physics3D, /// /// Use 2D physics to determine proximity. /// Physics2D }; /// /// The maximim range that objects will be visible at. /// [TooltipAttribute("The maximum range that objects will be visible at.")] public int visRange = 10; /// /// How often (in seconds) that this object should update the set of players that can see it. /// [TooltipAttribute("How often (in seconds) that this object should update the set of players that can see it.")] public float visUpdateInterval = 1.0f; // in seconds /// /// Which method to use for checking proximity of players. /// [TooltipAttribute("Which method to use for checking proximity of players.\n\nPhysics3D uses 3D physics to determine proximity.\n\nPhysics2D uses 2D physics to determine proximity.")] public CheckMethod checkMethod = CheckMethod.Physics3D; /// /// Flag to force this object to be hidden for players. /// If this object is a player object, it will not be hidden for that player. /// [TooltipAttribute("Enable to force this object to be hidden from players.")] public bool forceHidden = false; float m_VisUpdateTime; void Update() { if (!NetworkServer.active) return; if (Time.time - m_VisUpdateTime > visUpdateInterval) { GetComponent().RebuildObservers(false); m_VisUpdateTime = Time.time; } } // called when a new player enters public override bool OnCheckObserver(NetworkConnection newObserver) { if (forceHidden) return false; // this cant use newObserver.playerControllers[0]. must iterate to find a valid player. GameObject player = null; for (int i = 0; i < newObserver.playerControllers.Count; i++) { var p = newObserver.playerControllers[i]; if (p != null && p.gameObject != null) { player = p.gameObject; break; } } if (player == null) return false; var pos = player.transform.position; return (pos - transform.position).magnitude < visRange; } public override bool OnRebuildObservers(HashSet observers, bool initial) { if (forceHidden) { // ensure player can still see themself var uv = GetComponent(); if (uv.connectionToClient != null) { observers.Add(uv.connectionToClient); } return true; } // find players within range switch (checkMethod) { case CheckMethod.Physics3D: { var hits = Physics.OverlapSphere(transform.position, visRange); for (int i = 0; i < hits.Length; i++) { var hit = hits[i]; // (if an object has a connectionToClient, it is a player) var uv = hit.GetComponent(); if (uv != null && uv.connectionToClient != null) { observers.Add(uv.connectionToClient); } } return true; } case CheckMethod.Physics2D: { var hits = Physics2D.OverlapCircleAll(transform.position, visRange); for (int i = 0; i < hits.Length; i++) { var hit = hits[i]; // (if an object has a connectionToClient, it is a player) var uv = hit.GetComponent(); if (uv != null && uv.connectionToClient != null) { observers.Add(uv.connectionToClient); } } return true; } } return false; } // called hiding and showing objects on the host public override void OnSetLocalVisibility(bool vis) { SetVis(gameObject, vis); } static void SetVis(GameObject go, bool vis) { foreach (var r in go.GetComponents()) { r.enabled = vis; } for (int i = 0; i < go.transform.childCount; i++) { var t = go.transform.GetChild(i); SetVis(t.gameObject, vis); } } } }