1. 程式人生 > >[專欄精選]Unity中動態構建NavMesh

[專欄精選]Unity中動態構建NavMesh

本文節選自洪流學堂公眾號專欄《鄭洪智的Unity2018課》,未經允許不可轉載。

洪流學堂公眾號回覆專欄,檢視更多專欄文章。


小新:“Unity內建的Navigation系統是不錯,挺好用,但是我發現個致命問題”
大智:“說說看?”
小新:“導航系統對於靜態場景沒什麼問題,但是如果是動態生成的場景,那是不是就不能用了?”
大智:“確實,如果是動態生成的場景,就不能直接用了。但是Navigation系統有一個官方的擴充套件,雖然沒有直接包含在Unity引擎的安裝包裡,但是是Unity官方提供的。”

點選此連結可以檢視對應的元件

大智:“在Navigation視窗中可以看到這樣的連結字樣,也可以開啟對應的Github網站(

https://github.com/Unity-Technologies/NavMeshComponents)。”
小新:“哇,那你快給我仔細講講,原來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物體。

使用方法

點選選單欄中 GameObjectAI > NavMesh Surface。點選後會建立一個空物體,上面包含NavMeshSurface元件。一個場景可以包含多個NavMeshSurface物體。

也可以給任何物體新增NavMeshSurface元件,這種情況非常適合一個物體的所有子物體來構建NavMesh的情況。

屬性詳解

Agent Type 使用這個NavMeshSurface的Agent型別。用於NavMesh的生成和尋路。

Collect Objects 用於生成NavMesh的物體。

  • All 所有active的物體
  • Volume 選中該選項時,可以在場景中編輯一個盒子,盒子所包圍的物體用來生成NavMesh。

Volume選項時的包圍盒

  • 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,帶你從入門到精通。