This document is about: QUANTUM 3
SWITCH TO

Importing A Unity Navmesh

Quantum 導航網格生成是基於 Unity 導航網格管線構建的。Unity 導航網格三角剖分會被匯入並烘焙為 Quantum 導航網格二進位格式。

烘焙過程會將世界座標寫入 Quantum 導航網格,因為僅支援位於原點的導航網格。與 Quantum 物理系統類似,建議遊戲玩法在原點附近進行,以避免定點精度問題。

匯入 Unity 導航網格

  • 透過Unity Package Manager > Unity Registry將 AI 導航套件com.unity.ai.navigation新增至 Unity 專案。

    AI Navigation package
  • 建立並設定 Unity 導航網格表面 (Navmesh Surface)。

    Create a surface
  • 在地圖QuantumMapData下建立新的 GameObject,並新增QuantumMapNavMeshUnity指令碼。

    Create script
  • 將表面 GameObject 新增至Nav Mesh Surfaces清單。

    Add a Surface
  • 選取地圖物件,在Bake All Mode選項中啟用Everything,然後按一下 Bake All。控制台將記錄導航網格匯入訊息。

    Imported Unity NavMesh 'Navmesh', cleaned up 7 vertices, found 1 region(s), found 0 link(s)
    
  • Quantum 導航網格資產會烘焙為兩個資產檔案:導航網格資產和第二個二進位資料資產(後綴為_data),它們會放置在地圖資產旁邊。

    Navmesh assets
  • 烘焙後,導航網格資產會在QuantumMapData指令碼的Nav Mesh Links中被參考。

    Map navmesh references
  • 選取地圖物件以顯示 Quantum 導航網格 gizmo。開啟 Quantum Gizmo 疊加功能表以切換不同類型的 gizmo 繪製(在場景標籤上按右鍵 > 疊加功能表 > Quantum Gizmos)。

    Show Quantum navmesh gizmos
  • (可選)在QuantumEditorSettings中切換不同自動建置模式觸發器的導航網格建置。

    Auto build modes
  • Quantum.Core.NavigationSystem新增至遊戲啟動時在RuntimeConfig上設定的SystemsConfig中。預設配置已正確新增並啟用該系統。

    Auto build modes

匯入設定

從 Unity 導航網格轉換為 Quantum 導航網格時,會使用可透過QuantumMapNavMeshUnity指令碼自訂的匯入設定。

WeldIdenticalVertices Unity 導航網格是一組非連接的三角形集合。此選項非常重要,用於合併共用頂點。
WeldVertexEpsilon 不要將 epsilon 設得太小,否則可能會錯過需要融合的頂點;也不要將其設得太大,否則會使導航網格變形。
DelaunayTriangulation 此選項會使用德勞內三角剖分(Delaunay triangulation)對匯入的 Unity 導航網格進行後處理,以生成分佈更均勻的三角形(重新排列長三角形)。
DelaunayTriangulationRestrictToPlanes O在 3D 導航網格上,德勞內三角剖分在重新排列三角形時可能會使斜坡上的導航網格變形。這種行為在 Unity 的導航網格上也很明顯,當導航網格高度用於遊戲玩法(例如在導航網格上行走)時可能會影響遊戲。 勾選此選項可將三角剖分限制在同一平面內的三角形。
FixTrianglesOnEdges 匯入的頂點有時會位於其他三角形邊緣上,這會導致不必要的邊界檢測。啟用此選項可分割此類三角形。
FixTrianglesOnEdgesEpsilon 大型導航網格在檢測到誤報邊界時可能需要增大此值(例如設為 0.001)。最小值 = float.Epsilon。
FixTrianglesOnEdgesHeightEpsilon 使高度偏移量明顯大於 FixTrianglesOnEdgesEpsilon,以便更好地檢測退化三角形。如果導航網格變形,請選擇較小的 epsilon。最小值 = float.Epsilon。預設值為 0.05。
LinkErrorCorrection 自動將導航網格連結位置校正到最近的三角形,搜尋距離為此值(預設為 0)。
ClosestTriangleCalculation 地圖網格中沒有導航網格的區域需要檢測最近的相鄰區域。此計算速度很慢。SpiralOut 選項會快得多,但 fallback 三角形可能為 null。
ClosestTriangleCalculation Depth 使用 SpiralOut 時,向每個方向搜尋三角形的單元格數量。
EnableQuantum_XY 僅在設定了 QUANTUM_XY 定義時可見。開啟此選項,導航網格烘焙將翻轉 Y 和 Z,以支援在 XY 平面上生成的導航網格。
MinAgentRadius 導航網格支援的最小代理半徑。此值是導航網格與可見邊界之間的邊距。在編輯器中烘焙時,此值會透過從 Unity 導航網格烘焙設定(或表面設定)中檢索而被覆寫。
ImportRegionMode 禁用或更改匯入區域模式。有關更多詳細資訊,請參閱使用導航網格區域部分。預設為簡單(Simple)。
RegionDetectionMargin 人工邊距是必要的,因為導航網格三角剖分與原始大小不太匹配。此值會新增到導航網格區域,並與所有 Quantum 區域指令碼進行檢查,以選擇正確的區域 ID。
RegionAreaIds 將轉換為 Quantum 區域的 Unity 區域 ID。可以使用區域名稱(簡單模式)或明確的區域名稱(進階模式)。

地圖上的導航網格設定

QuantumMapData指令碼有兩個相關的導航網格設定:序列化類型以及導航網格網格和世界大小。這兩個設定都會在烘焙期間套用並複製到導航網格資產。

導航網格序列化類型

此設定控制導航網格資產中序列化多少資產內容,以及在載入時生成多少內容。它可用於減小資產大小,這在執行時建立資產並傳送給用戶端時可能很有用(請參閱自訂導航網格生成)。

Navmesh Area Gizmos
Full 序列化完整資料,但在載入後計算中繼資料。

預設值。
中等大小
FullWithMetaData 序列化完整資料和中繼資料(例如法線)。 最大大小
BakeDataOnly 僅序列化 NavMeshBakeData,並在執行時烘焙導航網格 NavMesh。 最小大小

導航網格區域與格線

當在 Quantum 導航網格疊加功能表中開啟時,場景中會渲染NavMesh AreaNavMesh Grid的Gizmos。

Navmesh Area Gizmos

可透過在NavMesh Settings標題下選取QuantumMapData指令碼來配置網格。X 和 Y/Z 方向的網格單元格數量以及網格節點大小(每個單元格的 Unity 單位維度)決定了整體網格大小。

Navmesh Area Map Data

導航網格網格區域需要包含整個導航網格(左側螢幕截圖中的藍色方塊)。

網格單元格(右側螢幕截圖中的黃色正方形)需要合理的大小,以避免包含太多單獨的導航網格三角形。這是在導航網格資料大小和性能之間的權衡。單元格越小,資料結構越大,但尋路期間需要處理的三角形越少。

Navmesh Area
Navmesh Area Grid

即使導航網格世界位置不在原點附近,它仍然必須位於網格區域內。

自訂導航網格烘焙回調

可透過繼承MapDataBakerCallback類別的回調來擴充導航網格烘焙過程。

將以下指令碼新增至QuantumUser/Editor中。

QuantumMapBakeAssembly屬性是烘焙過程找到回呼所必需的。

C#

[assembly: Quantum.QuantumMapBakeAssembly]

namespace Quantum.Editor
{
  using System.Collections.Generic;
  using UnityEngine;

  public class NavmeshBakeCallback : MapDataBakerCallback
  {
    public override void OnBeforeBakeNavMesh(QuantumMapData data)
    {
      // Before any navmesh baking takes place.
    }

    public override void OnCollectNavMeshBakeData(QuantumMapData data, List<NavMeshBakeData> navMeshBakeData)
    {
      // Unity navmesh surfaces have been imported and bake data is already filled out.
      Debug.Log($"Found {navMeshBakeData.Count} navmesh bake data");
    }


    public override void OnCollectNavMeshes(QuantumMapData data, List<NavMesh> navmeshes)
    {
      // Quantum navmesh have been baked.
    }

    public override void OnBakeNavMesh(QuantumMapData data) {
      // Quantum navmeshes have been saved to assets.
    }

    // abstract methods have to be implemented but not needed here
    public override void OnBake(QuantumMapData data) { }
    public override void OnBeforeBake(QuantumMapData data) { }
  }
}
Back to top