NavMeshPrefabInstance.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using UnityEngine.AI;
  4. [ExecuteInEditMode]
  5. [DefaultExecutionOrder(-102)]
  6. public class NavMeshPrefabInstance : MonoBehaviour
  7. {
  8. [SerializeField]
  9. NavMeshData m_NavMesh;
  10. public NavMeshData navMeshData
  11. {
  12. get { return m_NavMesh; }
  13. set { m_NavMesh = value; }
  14. }
  15. [SerializeField]
  16. bool m_FollowTransform;
  17. public bool followTransform
  18. {
  19. get { return m_FollowTransform; }
  20. set { SetFollowTransform(value); }
  21. }
  22. NavMeshDataInstance m_Instance;
  23. // Position Tracking
  24. static readonly List<NavMeshPrefabInstance> s_TrackedInstances = new List<NavMeshPrefabInstance>();
  25. public static List<NavMeshPrefabInstance> trackedInstances {get {return s_TrackedInstances; }}
  26. Vector3 m_Position;
  27. Quaternion m_Rotation;
  28. void OnEnable()
  29. {
  30. AddInstance();
  31. if (m_Instance.valid && m_FollowTransform)
  32. AddTracking();
  33. }
  34. void OnDisable()
  35. {
  36. m_Instance.Remove();
  37. RemoveTracking();
  38. }
  39. public void UpdateInstance()
  40. {
  41. m_Instance.Remove();
  42. AddInstance();
  43. }
  44. void AddInstance()
  45. {
  46. #if UNITY_EDITOR
  47. if (m_Instance.valid)
  48. {
  49. Debug.LogError("Instance is already added: " + this);
  50. return;
  51. }
  52. #endif
  53. if (m_NavMesh)
  54. m_Instance = NavMesh.AddNavMeshData(m_NavMesh, transform.position, transform.rotation);
  55. m_Rotation = transform.rotation;
  56. m_Position = transform.position;
  57. }
  58. void AddTracking()
  59. {
  60. #if UNITY_EDITOR
  61. // At runtime we don't want linear lookup
  62. if (s_TrackedInstances.Contains(this))
  63. {
  64. Debug.LogError("Double registration of " + this);
  65. return;
  66. }
  67. #endif
  68. if (s_TrackedInstances.Count == 0)
  69. NavMesh.onPreUpdate += UpdateTrackedInstances;
  70. s_TrackedInstances.Add(this);
  71. }
  72. void RemoveTracking()
  73. {
  74. s_TrackedInstances.Remove(this);
  75. if (s_TrackedInstances.Count == 0)
  76. NavMesh.onPreUpdate -= UpdateTrackedInstances;
  77. }
  78. void SetFollowTransform(bool value)
  79. {
  80. if (m_FollowTransform == value)
  81. return;
  82. m_FollowTransform = value;
  83. if (value)
  84. AddTracking();
  85. else
  86. RemoveTracking();
  87. }
  88. bool HasMoved()
  89. {
  90. return m_Position != transform.position || m_Rotation != transform.rotation;
  91. }
  92. static void UpdateTrackedInstances()
  93. {
  94. foreach (var instance in s_TrackedInstances)
  95. {
  96. if (instance.HasMoved())
  97. instance.UpdateInstance();
  98. }
  99. }
  100. #if UNITY_EDITOR
  101. void OnValidate()
  102. {
  103. // Only when the instance is valid (OnEnable is called) - we react to changes caused by serialization
  104. if (!m_Instance.valid)
  105. return;
  106. // OnValidate can be called several times - avoid double registration
  107. // We afford this linear lookup in the editor only
  108. if (!m_FollowTransform)
  109. {
  110. RemoveTracking();
  111. }
  112. else if (!s_TrackedInstances.Contains(this))
  113. {
  114. AddTracking();
  115. }
  116. }
  117. #endif
  118. }