This document is about: QUANTUM 3
SWITCH TO

Using Navmesh Regions

Quantum 導航網格區域是預定義(編輯時)的導航網格區域,可在運行時按代理開啟 / 關閉或過濾,且性能開銷極小。考慮到確定性回滾的性能因素,區域是 Unity 動態導航網格雕刻的一種折中方案。

有兩種區域生成模式可供選擇。

簡單模式 高級模式
最大區域數量 29 512
工具支持 直接使用 Unity 導航區域 ID 需要在級別幾何體內設置額外的區域腳本

選擇QuantumMapNavMeshUnity腳本可更改模式。

Walkable區域始終會轉換為區域0,並稱為MainArea

地圖的所有區域都可在 Map.Regions列表中訪問。區域 ID 是一個整數,指的是該地圖內區域的索引,可通過Map.RegionMap查找獲取。

Region Import Modes

導入導航網格區域 - 簡單模式

選擇一個場景對象,為其添加NavMesh Modifier腳本,啟用Override Area並設置所需的區域類型。在 Unity 導航窗口中定義更多 Unity 導航區域類型。

NavMesh Modifier

選擇QuantumMapNavMeshUnity腳本,啟用Simple區域導入模式。然後切換應轉換為 Quantum 區域的 Unity 區域。

NavMesh Modifier

烘焙 Quantum 導航網格,並使用導航網格 gizmos 驗證導入的區域。區域以洋紅色顯示。

Baked simple region

選擇QuantumMapEntity可查看導入的區域名稱。

NavMesh map

導入導航網格區域 - 高級模式

由於 Unity 導航區域 ID 的數量有限,因此不直接使用它們,而是在烘焙期間使用QuantumNavMeshRegion腳本將 Unity 導航網格的部分區域「標記」為導航區域。標記的導航網格三角形會擴展為島嶼,然後匹配回它們原始的 QuantumNavMeshRegion邊界框,最終獲得正確的區域 ID。

Unity navmesh

步驟 1:打開 Unity 導航窗口(Window > AI > Navigation),添加一個新的導航區域,例如命名為QuantumRegion

Unity Navigation window

步驟 2:選擇MapNavMeshUnity腳本,將區域導入模式設為 Advanced ,並啟用 Unity 導航區域QuantumRegion

由於導航網格三角形的生成並非 100% 精確,RegionDetectionMargin 用於定義擬合期間的邊距。當區域導入失敗時,可以增大該值。但如果該值過大,可能會在檢測相鄰區域時出現問題。

Add Region Area

步驟 3:創建區域投射器腳本。

選擇或創建一個帶有MeshRenderer的遊戲對象,並附加MapNavMeshRegion腳本。

Region Setup

Unity 使用MeshRenderer將區域投射到導航網格上。創建一個帶有MeshRenderer的遊戲對象,並附加MapNavMeshRegion。前提是導航網格表面已配置為收集渲染網格。

MeshRenderer和區域腳本只需在烘焙期間處於活動狀態。

Region Setup

區域Id用一個名稱標記該區域。多個MapNavMeshRegion可以使用相同的名稱,併為該區域貢獻內容。Id將註冊在地圖的Map.RegionMap下。區域索引指的是該區域在該數組中的位置。

CastRegion設為CastRegion

向該遊戲對象添加NavMesh Modifier腳本,啟用Override Area,並將 QuantumRegion設為區域類型。在 Unity 2022及更早版本中,區域腳本上的NavMeshHelper可用於切換區域。

Region Setup

當區域彼此靠近時,為每個區域選擇不同的區域類型。例如,區域A使用QuantumRegion,區域B使用QuantumRegion2

Region Setup

步驟 4:烘焙地圖和導航網格

Baked simple region

區域 API

獲取Foo區域並全局禁用它。

C#

var regionId = frame.Map.RegionMap["Foo"];
frame.NavMeshRegionMask->ToggleRegion(regionId, false);

NavMeshPathfinder組件也有一個RegionMask,可用於為各個代理關閉區域。

C#

var regionId = frame.Map.RegionMap["Foo"];
var agent = f.Unsafe.GetPointer<NavMeshPathfinder>(entity);
agent->RegionMask.ToggleRegion(regionId, false)

運行時 gizmos 顯示啟用和禁用的區域。

Inactive Regions
Inactive Regions

更改地圖時,可以在ISignalOnMapChanged信號期間運行FrameBase.ClearAllNavMeshRegions()來重置區域狀態。

C#

public class ResetRegionsSystem : SystemSignalsOnly, ISignalOnMapChanged {
    public void OnMapChanged(Frame frame, AssetRefMap previousMap) {
        frame.ClearAllNavMeshRegions();
    }
}

NavMeshRegionMask對象使用內部位集控制哪些區域處於啟用狀態。

默認 創建一個所有區域都啟用的區域掩碼
MainArea 創建一個只包含主區域的區域掩碼
Empty 創建一個沒有啟用區域的區域掩碼
HasValidRegions 如果掩碼至少設置了一個有效的區域(包括主區域),則返回true
HasValidNoneMainRegion 如果掩碼包含主區域以外的區域,則返回true
IsMainArea 檢查掩碼是否只包含主區域
Create(int region) 創建一個啟用了一個區域的NavMeshRegionMask
Create(int[] regionList) 使用區域 ID 列表創建一個掩碼
ToggleRegion(int region, bool enabled) 使用區域 ID 開啟或關閉一個區域
IsRegionEnabled(int region) 測試一個區域是否啟用
Clear() 重置掩碼並將所有區域設為啟用狀態
Back to top