summaryrefslogtreecommitdiff
path: root/YesCommander/Assets/ThirdParty/AI Navigation/1.0.0-exp.4/Build And Connect NavMesh Surfaces/Scripts/NavMeshPrefabInstance.cs
blob: 73735678b9b0b558a837ceec7513c9502cd67d3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.AI;

namespace Unity.AI.Navigation.Samples
{
    /// <summary>
    /// Associate existing NavMesh data to a prefab
    /// </summary>
    [ExecuteInEditMode]
    [DefaultExecutionOrder(-102)]
    public class NavMeshPrefabInstance : MonoBehaviour
    {
        [SerializeField]
        NavMeshData m_NavMesh;
        public NavMeshData navMeshData
        {
            get { return m_NavMesh; }
            set { m_NavMesh = value; }
        }
    
        [SerializeField]
        bool m_FollowTransform;
        public bool followTransform
        {
            get { return m_FollowTransform; }
            set { SetFollowTransform(value); }
        }
    
        NavMeshDataInstance m_Instance;
    
        // Position Tracking
        static readonly List<NavMeshPrefabInstance> s_TrackedInstances = new List<NavMeshPrefabInstance>();
        public static List<NavMeshPrefabInstance> trackedInstances { get { return s_TrackedInstances; } }
    
        Vector3 m_Position;
        Quaternion m_Rotation;
    
        void OnEnable()
        {
            AddInstance();
    
            if (m_Instance.valid && m_FollowTransform)
                AddTracking();
        }
    
        void OnDisable()
        {
            m_Instance.Remove();
            RemoveTracking();
        }
    
        /// <summary>
        /// Update NavMeshData instance with the current position and rotation
        /// </summary>
        public void UpdateInstance()
        {
            m_Instance.Remove();
            AddInstance();
        }
    
        void AddInstance()
        {
    #if UNITY_EDITOR
            if (m_Instance.valid)
            {
                Debug.LogError("Instance is already added: " + this);
                return;
            }
    #endif
            if (m_NavMesh)
                m_Instance = NavMesh.AddNavMeshData(m_NavMesh, transform.position, transform.rotation);
    
            m_Rotation = transform.rotation;
            m_Position = transform.position;
        }
    
        void AddTracking()
        {
    #if UNITY_EDITOR
            // At runtime we don't want linear lookup
            if (s_TrackedInstances.Contains(this))
            {
                Debug.LogError("Double registration of " + this);
                return;
            }
    #endif
            if (s_TrackedInstances.Count == 0)
                NavMesh.onPreUpdate += UpdateTrackedInstances;
            s_TrackedInstances.Add(this);
        }
    
        void RemoveTracking()
        {
            s_TrackedInstances.Remove(this);
            if (s_TrackedInstances.Count == 0)
                NavMesh.onPreUpdate -= UpdateTrackedInstances;
        }
    
        void SetFollowTransform(bool value)
        {
            if (m_FollowTransform == value)
                return;
            m_FollowTransform = value;
            if (value)
                AddTracking();
            else
                RemoveTracking();
        }
    
        bool HasMoved()
        {
            return m_Position != transform.position || m_Rotation != transform.rotation;
        }
    
        static void UpdateTrackedInstances()
        {
            foreach (var instance in s_TrackedInstances)
            {
                if (instance.HasMoved())
                    instance.UpdateInstance();
            }
        }
    
    #if UNITY_EDITOR
        void OnValidate()
        {
            // Only when the instance is valid (OnEnable is called) - we react to changes caused by serialization
            if (!m_Instance.valid)
                return;
            // OnValidate can be called several times - avoid double registration
            // We afford this linear lookup in the editor only
            if (!m_FollowTransform)
            {
                RemoveTracking();
            }
            else if (!s_TrackedInstances.Contains(this))
            {
                AddTracking();
            }
        }
    #endif
    }
}