Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Rebuilding navmeshes at runtime

Discussion in 'Navigation' started by CarlBellDev, Apr 25, 2017.

  1. CarlBellDev

    CarlBellDev

    Joined:
    Apr 25, 2017
    Posts:
    4
    I've been using the new navmesh scripts from github. I've managed to instantiate prefab tiles with the correct navmesh geometry but every time a new tile is added it all of the navmeshes are moved away from their gameobject. The only tile unaffected is the first one which is neither moved or rotated.

    The script is almost identical to the "NavMeshPrefabInstance" script on github with a single function added to trigger a rebuild.

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

    00.png 01.png 02.png