using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.AI; namespace Unity.AI.Navigation { /// Component that modifies the properties of the GameObjects used for building a NavMesh. /// The properties apply to the current GameObject and can be optionally applied recursively to all its children /// in the hierarchy. This modifier overrides the properties set to this GameObject by /// any other NavMeshModifier in the parent hierarchy. [ExecuteAlways] [DefaultExecutionOrder(-103)] [AddComponentMenu("Navigation/NavMesh Modifier", 32)] [HelpURL(HelpUrls.Manual + "NavMeshModifier.html")] public class NavMeshModifier : MonoBehaviour { #pragma warning disable 0414 // Serialized version is used to upgrade older serialized data to the current format. // Version 0: Initial version. [SerializeField, HideInInspector] byte m_SerializedVersion = 0; #pragma warning restore 0414 [SerializeField] bool m_OverrideArea; [SerializeField] int m_Area; [SerializeField] bool m_OverrideGenerateLinks; [SerializeField] bool m_GenerateLinks; [SerializeField] bool m_IgnoreFromBuild; [SerializeField] bool m_ApplyToChildren = true; // List of agent types the modifier is applied for. // Special values: empty == None, m_AffectedAgents[0] =-1 == All. [SerializeField] List m_AffectedAgents = new List(new int[] { -1 }); // Default value is All /// Gets or sets whether to assign the type to this object instead of the . /// The area type information is used when baking the NavMesh. /// public bool overrideArea { get { return m_OverrideArea; } set { m_OverrideArea = value; } } /// Gets or sets the area type applied by this GameObject. /// The range of useful values is from 0 to 31. Higher values always take precedence over lower values in the case when the surfaces of more GameObjects intersect each other to produce a NavMesh in the same region. A value of 1 has the highest priority over all the other types and it means "not walkable". Consequently, the surface of a GameObject with an area of 1 produces a hole in the NavMesh. This property has the same meaning as . /// public int area { get { return m_Area; } set { m_Area = value; } } /// Gets or sets whether the default links generation condition for the GameObject and its children should be overridden. public bool overrideGenerateLinks { get { return m_OverrideGenerateLinks; } set { m_OverrideGenerateLinks = value; } } /// Gets or sets whether this object is included in the link generation process. public bool generateLinks { get { return m_GenerateLinks; } set { m_GenerateLinks = value; } } /// Gets or sets whether the NavMesh building process ignores this GameObject and its children. public bool ignoreFromBuild { get { return m_IgnoreFromBuild; } set { m_IgnoreFromBuild = value; } } /// Gets or sets whether this GameObject's children also use the modifier settings. public bool applyToChildren { get { return m_ApplyToChildren; } set { m_ApplyToChildren = value; } } static bool s_RebuildNavMeshModifiers = true; static List s_NavMeshModifiers = new List(); static readonly HashSet s_NavMeshModifiersSet = new HashSet(); /// Gets the list of all the components that are currently active in the scene. Copies the returned list from /// an internal container and updates it whenever a NavMeshModifier is enabled or disabled. public static List activeModifiers { get { if (s_RebuildNavMeshModifiers) { s_NavMeshModifiers = s_NavMeshModifiersSet.ToList(); s_RebuildNavMeshModifiers = false; } return s_NavMeshModifiers; } } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void ClearNavMeshModifiers() { s_NavMeshModifiers.Clear(); s_NavMeshModifiersSet.Clear(); } void OnEnable() { RegisterModifier(); } void OnDisable() { UnregisterModifier(); } void RegisterModifier() { if (s_NavMeshModifiersSet.Add(this)) { s_RebuildNavMeshModifiers = true; } } void UnregisterModifier() { if (s_NavMeshModifiersSet.Remove(this)) { s_RebuildNavMeshModifiers = true; } } /// Verifies whether this modifier can affect in any way the generation of a NavMesh for a given agent type. /// The identifier of an agent type that originates from . /// true if this component can affect the NavMesh built for the given agent type; otherwise false. public bool AffectsAgentType(int agentTypeID) { if (m_AffectedAgents.Count == 0) return false; if (m_AffectedAgents[0] == -1) return true; return m_AffectedAgents.IndexOf(agentTypeID) != -1; } } }