[專欄精選]Unity中動態構建NavMesh
本文節選自洪流學堂公眾號專欄《鄭洪智的Unity2018課》,未經允許不可轉載。
洪流學堂公眾號回覆專欄
,檢視更多專欄文章。
小新:“Unity內建的Navigation系統是不錯,挺好用,但是我發現個致命問題”
大智:“說說看?”
小新:“導航系統對於靜態場景沒什麼問題,但是如果是動態生成的場景,那是不是就不能用了?”
大智:“確實,如果是動態生成的場景,就不能直接用了。但是Navigation系統有一個官方的擴充套件,雖然沒有直接包含在Unity引擎的安裝包裡,但是是Unity官方提供的。”
大智:“在Navigation視窗中可以看到這樣的連結字樣,也可以開啟對應的Github網站(
小新:“哇,那你快給我仔細講講,原來Unity比我想象的還要強大很多,哈哈”
大智:“得益於Unity的擴充套件性,其實很多Unity自己沒有的功能都有第三方的外掛進行解決,而且做得很好。”
小新:“希望有一天我也能寫出幫助別人解決問題的外掛”
大智:“好好學,一定會有這一天的!今天我就給你講講這個NavMeshComponent”
NavMeshComponent
NavMeshComponent給NavMesh的構建和使用提供了很多額外的控制功能,可以在執行時和編輯器中使用。
安裝
NavMeshComponent並沒有直接包含在Unity中,需要通過這個連結(https://github.com/Unity-Technologies/NavMeshComponents)安裝下載。具體的步驟是:
1、開啟上面的連結
2、點選圖中的Release
3、選擇你的Unity版本對應的NavMeshComponent版本。
4、下載解壓以後,可以使用Unity開啟該工程。如果要在已有的工程中使用,可以將Assets/NavMeshComponents
目錄複製到已有工程中。另外 Assets/Examples
目錄中有示例場景。
元件介紹
NavMeshComponents包含4個元件,分別是:
這裡我們介紹導航系統的四個元件:
- NavMeshSurface - 基於一種agent型別構建NavMesh。
- NavMeshModifier - 基於層次結構影響NavMesh區域型別的NavMesh生成。
- NavMeshModifierVolume - 根據體積影響NavMesh區域型別的NavMesh生成。
- NavMeshLink - 為一個agent型別連線相同或不同的NavMesh表面。
這些元件包含了構建和使用NavMeshes的高階控制,可以用於執行時和編輯時。
NavMesh Surface
NavMeshSurface元件用來設定針對一種agent型別的可行走的區域,並且在該區域構建NavMesh。在構建NavMesh時,會自動排除NavMeshAgent和NavMeshObstacle物體。
使用方法
點選選單欄中 GameObject > AI > NavMesh Surface。點選後會建立一個空物體,上面包含NavMeshSurface元件。一個場景可以包含多個NavMeshSurface物體。
也可以給任何物體新增NavMeshSurface元件,這種情況非常適合一個物體的所有子物體來構建NavMesh的情況。
屬性詳解
Agent Type 使用這個NavMeshSurface的Agent型別。用於NavMesh的生成和尋路。
Collect Objects 用於生成NavMesh的物體。
- All 所有active的物體
- Volume 選中該選項時,可以在場景中編輯一個盒子,盒子所包圍的物體用來生成NavMesh。
- Children NavMeshSurface元件所在物體的所有active子物體。
Include Layers 可以選擇用於生成NavMesh的layer。
Use Geometry 用於生成NavMesh的幾何體
- Render Meshes 使用物體的Mesh和Terrain資料
- Physics Colliders 使用物體的Collider和Terrain資料(使用這個選項時,agent可以移動到物體邊緣更近的地方)
Advanced settings 高階設定
Default Area 設定該NavMesh的Area
Override Voxel Size 設定Voxel尺寸
Override Tile Size 為了使烘焙過程能並行處理並且記憶體效率更高,場景被分割成多個小塊(瓦片)。NavMesh上可見的白線是瓦片的邊界。
預設瓦片大小為256個Voxel,這個值在記憶體使用效率和NavMesh分塊之間提供了良好的折衷。
要更改此預設瓦片大小,可以選中此複選框,然後在 Tile Size 欄位中輸入切片大小的體素數。
瓦片越小,NavMesh就越碎片化。這有時會導致agent走的不是最佳路徑。NavMesh雕刻也在瓦片上執行。如果有很多障礙物,通常可以設定更小的瓦片尺寸(例如大約64到128個體素)來加速雕刻。如果計劃在執行時烘焙NavMesh,請使用較小的瓦片大小來降低最大記憶體佔用。
Build Height Mesh 暫不支援
NavMesh Modifier
這個元件可以修改該物體及子物體的NavMesh構建屬性。這個元件會影響該物體及所有的子物體。如果子物體上也有NavMesh Modifier,則該NavMesh Modifier會重寫自己及其子物體的屬性。
NavMesh Modifier會影響NavMesh的構建,所以如果NavMesh Modifier的屬性進行了修改,需要重新構建NavMesh。
屬性詳解
Ignore From Build 選中時該物體及其所有子物體不會被構建進NavMesh。
Override Area Type 修改該物體及其所有子物體的Area型別。
Affected Agents 該元件影響的Agents。例如,你可以針對特定的Agent排除特定的障礙物。
NavMesh Modifier Volume
和NavMesh Modifier類似,但是此元件可以通過設定一個包圍盒來修改包圍盒中的物體的NavMesh屬性。
NavMesh Link
NavMesh Link可以在兩個NavMesh之間建立連結。可以是點到點的連結,也可以是縫隙之間的連結(會沿著入口邊緣最近位置跨越連結)。
屬性詳解
Agent Type 可以使用這個NavMeshLink的Agent型別。
Start Point 起點。相對於GameObject的位置。
End Point 終點。相對於GameObject的位置。
Swap按鈕 交換起點和終點的位置。
Align Transform按鈕 將GameObject的位置移到起點和終點的中心,並且朝向終點的位置。
Width 寬度。如果為0則通過兩個點連線,如果大於0通過兩條線連線。
Cost Modifier 非負值時,通過這個連結的代價是Cost Modifier乘以終點的距離。
Bidirectional 雙向。不勾選時只能單向尋路。
Area Type 設定該link的area型別。
總結
大智:“這些基本上就是NavMesh相關元件的一些介紹和用法。可以更靈活的在執行時建立、使用NavMesh。”
小新:“嗯,聽你梳理完之後感覺也不是很複雜,我要去親自嘗試一下。”
今日思考題
大智:“是的,建議你去動態生成一個場景,看看NavMesh是如何生成和變化的”
小新:“好,我馬上就去試”
大智:“收穫別忘了分享出來!也別忘了分享給你學Unity的朋友,也許能夠幫到他。”
洪流學堂公眾號回覆專欄
,檢視更多專欄文章。
《鄭洪智的Unity2018課》,傾盡我8年的開發經驗,結合最新的Unity2018,帶你從入門到精通。