Using Navmesh Regions
雖然考慮到Quantum中的確定性復原的效能考量,導航網格區域是對於Unity動態導航網格切割的妥協。它們可以用於動態地切換預先定義的導航網格的區域,並且只有非常少的效能額外負荷。
由於區域在三角形(無符號長)中被編碼為遮罩,一個地圖的不同區域識別碼的最大數量為64 (Navigation.Constants.MaxRegions
)。雖然可以針對不同的區域重新使用相同的識別碼。
主要Quantum導航網格(可行走)不是一個區域,並且不可被切換。
建立導航網格區域
第1步) Quantum區域附掛在Unity導航網格區域。建立一個新的區域。我們在以下圖片中選擇名稱Toggleable
,但是任何名稱都可以。
為了在您有相鄰的可切換的區域時進行偵測,它們將需要使用不同的區域識別碼。在這個情況下在此建立多個區域。
第2步) 新增新的區域到MapNavMeshUnity
,不然嵌入將不知道尋找哪些區域。
第3步) Unity使用物件MeshRenderer
將區域投射到導航網格上。以一個MeshRenderer
建立一個遊戲物件,並且附加MapNavMeshRegion
。
Id
是一個獨一無二的字串,其可以透過Map.RegionMap
從程式碼中存取,您之後可以在其中獲得區域識別碼(整數、旗標)。
CastRegion
必須被設定為CastRegion
。針對關閉網格連結,指令碼被重新使用,舉例而言,其不需要投射區域到導航網格。
在NavMeshHelper
之下,您可以再次檢查遊戲物件是否正確設定:舉例而言是否設定為static
,以及選取的區域是否是我們的區域。
當已安裝導航網格表面,偵測器看起來有一些不同。舉例而言,您需要新增一個NavMeshModifier
指令碼,以設定導航網格區域。
在匯入區域時,我們試著配對三角形到原始區域指令碼,並且對此使用網格的週框方塊。因為生成的三角形不是100%精確的,因此在MapNavMeshUnity
上的設定有一個RegionDetectionMargin
設定,其在調整符合時新增一些空間。如果沒有匯出區域,則增加此值,但如果它變得太大,則可能在偵測鄰近區域時產生一些問題。
順帶一提:生成區域的MeshRenderer
僅需要在嵌入時啟用..我們應該針對這個來新增一個工具..
第4步) 現在嵌入地圖,並且可看見導航網格中的著色三角形區域,其中的區域已被替換。
第5步) 在程式碼中切換區域為關閉,並且看著代理規避它。
C#
public override void OnInit(Frame f) {
var regionId = f.Map.RegionMap["foo"];
f.NavMeshRegionMask->ToggleRegion(regionId, false);
}
第6步) 可存取區域啟用,其儲存在幀中。
當載入新的地圖時,遮罩需要被重新設定。舉例而言,在ISignalOnMapChanged
信號時,運行FrameBase.ClearAllNavMeshRegions()
。
C#
public class ResetRegionsSystem : SystemSignalsOnly, ISignalOnMapChanged {
public void OnMapChanged(Frame f, AssetRefMap previousMap) {
f.ClearAllNavMeshRegions();
}
}
檢查NavMeshRegionMask
物件的API。這裡是一個簡單的概述:
NavMeshRegionMask.Default
有所有已啟用的區域(設定為1)NavMeshRegionMask.ToggleRegion(int region, bool enabled)
透過區域識別碼來切換一個區域。區域識別碼是位元移位的位移,並且可以透過使用Map.RegionMap
字典的名稱來被擷取。NavMeshRegionMask.IsRegionEnabled(int region)
檢查區域是否啟用。NavMeshRegionMask.IsSubset(NavMeshRegionMask)
可用於檢查在一個遮罩中的所有啟用區域是否也在另一個遮罩中啟用。NavMeshRegionMask.Clear()
設定所有區域為啟用。NavMeshRegionMask.HasValidRegions
當遮罩只有一個有效區域時傳回真。NavMeshRegionMask.IsMainArea
檢查遮罩是否為零,對於屬於主要導航網格區域且無法被切換關閉的三角形,此值將為真。