【Unity】Unity寻路系统讲解及Navigation实际应用
文章目錄
- 常見尋路方式
- 路點尋路(WayPoint)
- 單元格尋路(Grid)
- 導航系統(Navigation)
- 導航系統核心模塊
- 工作原理
- 尋路
- 跟隨路徑
- 躲避障礙物
- 移動代理
- 全局和局部
- 障礙物的兩種情況
- 描述網格外鏈接
- Navigation實際應用
- 準備場景
- 下載 Navigation
- 添加代理(Nav Mesh Agent)
- 設置代理
- 烘焙路網
- 創建終點
- 添加代碼
- 使用腳本
- 運行效果
- 尋路插件
常見尋路方式
Unity常用的尋路方式主要有以下幾種:
- 路點尋路(WayPoint)
- 單元格尋路(Grid)
- 導航系統(Navigation)
路點尋路(WayPoint)
路點尋路就是在地圖上指定一些路點,讓角色在路點之間移動。常用于一些固定路線的敵人或物體。
優點:路點尋路的優點是實現起來比較簡單,且占用資源少、計算開銷低。路線容易查看和編輯。
缺點:路線完全固定(有時會顯得很僵硬),每個路點都要人為設定。容易出現繞路、走回頭路和被障礙物卡住的情況。
單元格尋路(Grid)
單元格尋路就是把地圖分隔為多個格子,形成一個矩陣,每個格子標注是否可移動,角色在可移動的格子內尋路。有點類似于戰棋類游戲的走格子。
優點:實現簡單,路線可控,障礙物可控。
缺點:單元格密度大則開銷大,單元格密度小則行動很僵硬。經常出現90°轉角的情況,需要做平滑處理。不適合做3D游戲。
導航系統(Navigation)
Unity自帶了一套導航系統。導航系統允許使用從場景幾何體自動創建的導航網格來創建可在游戲世界中智能移動的角色。動態障礙物可讓您在運行時更改角色的導航,而網格外鏈接 (Off-Mesh Link) 可讓您構建特定動作,如打開門或從窗臺跳下。本部分將詳細介紹 Unity 的導航系統和尋路系統。
導航系統核心模塊
- 導航網格( Navigation Mesh,縮寫為 NavMesh),是一種數據結構,用于描述游戲世界的可行走表面,并允許在游戲世界中尋找從一個可行走位置到另一個可行走位置的路徑。該數據結構是從關卡幾何體自動構建或烘焙的。
- 導航網格代理 (NavMesh Agent) 組件可幫助您創建在朝目標移動時能夠彼此避開的角色。代理使用導航網格來推斷游戲世界,并知道如何避開彼此以及移動的障礙物。
- 網格外鏈接 (Off-Mesh Link) 組件允許您合并無法使用可行走表面來表示的導航捷徑。例如,跳過溝渠或圍欄,或在通過門之前打開門,全都可以描述為網格外鏈接。
- 導航網格障礙物 (NavMesh Obstacle) 組件可用于描述代理在世界中導航時應避開的移動障礙物。由物理系統控制的木桶或板條箱便是障礙物的典型例子。障礙物正在移動時,代理將盡力避開它,但是障礙物一旦變為靜止狀態,便會在導航網格中雕刻一個孔,從而使代理能夠改變自己的路徑來繞過它,或者如果靜止的障礙物阻擋了路徑,則代理可尋找其他不同的路線。
工作原理
導航系統需要自己的數據來表示游戲場景中的可行走區域。可行走區域定義了代理可在場景中站立和移動的位置。在 Unity 中,代理被描述為圓柱體。可行走區域是通過測試代理可站立的位置從場景中的幾何體自動構建的。然后,這些位置連接到場景幾何體之上覆蓋的表面。該表面稱為導航網格(簡稱 NavMesh)。
導航網格將該表面存儲為凸多邊形。凸多邊形是一種有用的表示,因為我們知道多邊形內的任意兩點之間沒有障礙物。除了多邊形邊界之外,我們還存儲有關哪些多邊形彼此相鄰的信息。這使我們能夠推斷整個可行走區域。
尋路
要尋找場景中兩個位置之間的路徑,我們首先需要將起始位置和目標位置映射到各自最近的多邊形。然后,我們從起始位置開始搜索,訪問所有鄰居,直到我們到達目標多邊形。通過跟蹤被訪問的多邊形,我們可以找出從起點到目標的多邊形序列。一種尋路的常用算法是 A*(發音為“A star”),這也是 Unity 使用的算法。
跟隨路徑
描述從起點到目標多邊形的路徑的多邊形序列稱為“走廊”(corridor)。代理將始終朝著走廊的下一個可見拐角移動,直至到達目標。如果一個簡單游戲只有一個代理在場景中移動,可一次性找出走廊的所有拐角,并推動角色沿著連接拐角的線段移動。
在多個代理同時移動的情況下,它們需要在避開彼此時偏離原始路徑。試圖使用由線段組成的路徑來糾正這種偏差很快變得非常困難并且容易出錯。
由于每一幀中的代理移動距離非常小,我們可以使用多邊形的連接來修復走廊,以防我們需要稍微繞道而行。然后,我們快速找到下一個需要抵達的可見拐角。
躲避障礙物
轉向邏輯將采用下一個拐角的位置并基于該位置計算出到達目標所需的方向和速度。使用所需的速度移動代理可能會導致與其他代理發生碰撞。
障礙躲避系統將選擇新的速度,該速度可平衡“代理在所需方向上移動”和“防止未來與其他代理及導航網格邊緣發生碰撞”這兩個問題。Unity 采用倒數速度障礙物 (RVO) 來預測和防止碰撞。
移動代理
最后在轉向和障礙躲避之后計算最終速度。在 Unity 中使用簡單的動態模型來模擬代理,該模型還考慮了加速度以實現更自然和平滑的移動。
在此階段,您可以將速度從模擬的代理提供給動畫系統,從而使用根運動移動角色,或讓導航系統處理該問題。
使用任一方法移動代理后,模擬代理位置將移動并約束到導航網格。最后這一小步對于實現強大的導航功能非常重要。
全局和局部
關于導航需要了解的最重要事項之一是全局和局部導航之間的區別。
全局導航用于在整個世界中尋找走廊。在整個世界中尋路是一項代價高昂的操作,需要相當多的處理能力和內存。
描述路徑的多邊形的線性列表是用于轉向的靈活數據結構,并可在代理的位置移動時進行局部調整。局部導航試圖確定如何有效移動到下一個拐角而不與其他代理或移動對象發生碰撞。
障礙物的兩種情況
許多導航應用需要其他類型的障礙物而不僅僅是其他代理。這些障礙物可能是射擊游戲中的常規板條箱和木桶,或者是車輛。可使用局部障礙躲避或全局尋路功能來應對障礙物。
當障礙物為移動狀態時,最好使用局部障礙躲避功能進行處理。這樣,代理可預測性地避開障礙物。當障礙物變為靜止狀態并可認為其阻擋了所有代理的路徑時,障礙物應該影響全局導航,即導航網格。
更改導航網格稱為“雕刻”(carving)。該過程將檢測障礙物的哪些部分會接觸導航網格并在導航網格中雕刻孔洞。此操作的計算成本十分高昂,因此這也是應該使用碰撞躲避功能來處理移動障礙物的另一個充分理由。
局部碰撞躲避功能也常用于繞過稀疏分散的障礙物。由于算法是局部的,因此它只考慮即將發生的碰撞,并且不能繞過陷阱或處理障礙物擋路的情況。這些情況可使用雕刻技術來解決。
描述網格外鏈接
導航網格多邊形之間的連接是使用尋路系統內的鏈接描述的。有時需要讓代理在不可步行位置進行導航,例如,跳過圍欄或穿過關閉的門。這些情況需要知道動作的位置。
可使用網格外鏈接來注釋這些動作;此類鏈接會告訴尋路器 (pathfinder) 存在一條通過指定鏈接的路線。稍后在跟隨路徑時可訪問此鏈接,并可執行特殊動作。
前面是照搬手冊中的介紹,下面上點干貨。
Navigation實際應用
準備場景
我們模擬一個塔防游戲,先畫一張簡圖。
然后使用MTE插件創建一張簡易的地圖(暫未完成),截圖如下:
注意:關于MTE的使用請參考另外一篇文章:【Unity】Unity插件:地形編輯器MTE(Mesh Terrain Editor))
下載 Navigation
因為Unity中的 Navigation 不是自帶的,需要我們到包管理器中去下載。步驟如下:
等待一會,Navigation 的包就下載好了。
添加代理(Nav Mesh Agent)
我們在場景中建立一個空物體,下面放一個 Cube ,然后給它添加導航代理(Nav Mesh Agent),這個代理讓導航系統能夠幫助我們進行角色移動。
設置代理
代理設置內容都很簡單,先根據角色的大小,通過 Obstacle Avoidance 設置角色的半徑、高度、質量等。然后通過 Steering 設置角色的移動速度、角速度、加速度等。如下圖:
烘焙路網
設置好代理后我們進行路面的烘焙。先打開烘焙窗口: Window --> AI --> Navigation 。
在 Bake 選項卡中點擊 Bake 按鈕進行烘焙。
烘焙結果如下:
創建終點
在場景中創建一個膠囊模型,更名為 Cristal 。
添加代碼
創建一個名為 NavTest 的腳本,具體代碼如下:
using UnityEngine; using UnityEngine.AI;/// <summary> /// 尋路系統 /// </summary> public class NavTest : MonoBehaviour {private NavMeshAgent agent;public Transform target;private void Start(){agent = this.GetComponent<NavMeshAgent>();}private void Update(){if (agent != null){bool flag = agent.SetDestination(target.position);}} }使用腳本
將腳本給到剛才創建的Cube的父對象上,然后將終點的 Cristal 拖拽到腳本的 Target 屬性中。
運行效果
先看看固定視角的尋路。
再看看角色視角的尋路。
到這里一個簡單的尋路功能就做好了。
其實除了 Unity 自帶的 Navigation 功能外,還有一些插件可以使用。
尋路插件
在Unity Asset Store中也有很多尋路插件可以使用,其原理也大部分與其他三種尋路方式相仿,我們可以自己下載下來試試。
關于 Navigation 中代理代理及障礙物的詳細講解,請參考另一篇文章:【Unity】導航基本組件:Nav Mesh Agent、Off Mesh Link、Nav Mesh Obstacle
更多內容請查看總目錄【Unity】Unity學習筆記目錄整理
總結
以上是生活随笔為你收集整理的【Unity】Unity寻路系统讲解及Navigation实际应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编辑器漏洞 EWebedtitor FC
- 下一篇: 权限管理框架Shiro简介