一個導航網格(也就是Navmesh)是世界幾何體簡化的表示法,被游戲代理用於在世界中進行導航。通常,代理(agent )有一個目標,或一個目的地,它試圖找到一個路徑,然后沿路徑導航到達目標。這個過程被稱為尋路。請注意,導航網格生成(或烘焙)是通過游戲開發者在編輯器內完成,而尋路是在運行時根據導航網格的代理來完成。
在復雜的游戲世界,可以有許多代理,動態的障礙,在世界不同地區不斷變化的可達程度。代理需要對這些變化動態作出反應。代理的尋路任務可以被打斷或者受到一些事情的影響,如與其他角色產生碰撞,改變地形的特征,物理障礙(如關門),那么到實際目的地的路徑就會有所更新。
在烘焙過程中是否進行自動網格鏈接(off mesh link generation)也取決於導航烘焙設置中的Jump distance (跳高距離)和Drop height(掉落高度)屬性。
導航網格層選擇自動生成網格鏈接,默認是內置層Jump層。這可以控制全局進行自動網格鏈接的成本。
1、NavMeshAgent組件
導航網格代理(NavMesh Agent )組件用於尋路,是存放代理如何在導航網格(NavMesh)中導航的信息的地方。
Radius:代理的半徑(這是代理的“個人遮護罩”,形成一個屏蔽罩,從而使其他代理無法通過此遮護罩)遮護罩可以形象的看成對象的collider
我為兩個對象的Radius都設為了2.5,效果圖如下:
那么右邊的對象無論怎么走,也都是無法進入左邊對象的遮護罩內的,也就是左邊對象的綠色線內的!效果如下:
兩個對象都是向同一個點移動,但是因為Radius“遮護罩”的原因,致使他們無法靠近,這就可以避免多個對象因為靠的太近造成亂象的情況!
當我們把Radius設為0.1時,就造成了下面的情況了:
Speed:速度,尋路的最大移動速度。代理通常需要在尋路時加速和減速(例如,在急轉彎時它會減緩速度)。速度往往被限制於路徑段的長度和花費在加速和剎車上的時間,但速度不會超過這個屬性設定的值,即使是在很長一段直的路徑上!
Acceleration:加速度: 作為尋路時代理的最大加速度,給出了 units / sec^2 。代理不能精確的跟隨導航系統計算的路徑線段,而是使用沿路徑航點作為中間目標,此值是代理可以加速邁向下一個關鍵點的最大值。
Angular Speed: 角速度:尋路時的最大轉動速度(度/秒)。這是在該代理能夠繞由航點定義的"拐角"的最大速率,實際的轉彎半徑也受代理的速度和最大加速度影響。
Stopping distance: 制動距離:制動距離。到目的地的距離小於這個值,代理減速。代理很少能精確的着陸在目標點,所以這個屬性可以用於設置一個可接受的范圍內,代理應該停止。較大的停止距離會給代理更多回旋余地在路徑的末尾,還可能避免突然剎車,轉彎或不真實的人工智能行為。
Auto Traverse Off Mesh Link: 自動遍歷OffMesh鏈接:自動移動並關閉OffMeshLinks,代理應該自動通過 OffMeshLinks 移動嗎?Off-mesh鏈接是用於連接NavMesh不相交的區域。通常,如果這個屬性設置為true,那么一個角色應該能夠自動通過或者穿過鏈路。然而,在它被設為false的情況下,那么一個鏈路代表一扇門或者其他障礙,那么角色需要“許可”才能越過
Auto Braking:代理應該自動剎車避免過度到達目的地嗎?如果代理需要移動的靠近目標點,那么它通常需要制動,以避免過度或沒完沒了的“繞着”目標區。如果這個屬性被設置為true,代理將自動剎車,當它接近目的地的時候
設為true的情況 設為false的情況
Auto Repath: 自動重新尋路:如果現有的部分已失效,獲得新的路徑。代理應該嘗試獲得一種新的路徑,如果現有的路徑無效?
Height: 高度:代理的高度(用於調試圖形)。就是設置的是“遮護罩”的高度,高度設置為和人物一樣高就行了,就相當於設置對象的collider一樣
Base offset: 基本偏移:碰撞幾何體相對於實際幾何體垂直的偏移。就是設置人物相對於“遮護罩”的垂直偏移
左邊人物的Base offset設為-1,右邊的設為2
程序運行后,兩個人物的狀態如下,可以看到,兩個對象都發生了垂直方向的相對偏移了!左邊的對象因為相對垂直偏移為-1,所以人物被擠到地形下面了,而右邊的相對偏移為2,所以人物被擠上去了!
Obstacle Avoidance Type: 障礙躲避類型,躲避的質量水平。這是個枚舉值,此屬性允許你權衡躲避障礙的精度和對實現這一目標所需的處理器負載。精確的質量值將很大程度取決於場景的復雜性,但作為一般性規則,更快的性能將會以犧牲質量為代價,反之亦然。
Avoidance Priority:避開優先級,代理執行避開時,低優先級的代理人被忽略。有效的范圍從0到99,最重要的= 0,最不重要= 99,默認= 50。
NavMesh Walkable: 導航網格行走:指定代理可以遍歷的導航網格層類型。指定哪些NavMesh層可以通行。改變walkableMask將使路徑失效
2、Off-mesh links組件
有時,場景中的靜態幾何體的導航網格不是全部相連在一起的(如上),從而使代理不能從世界場景的這一部分移動到另外的部分。
為了解決這個問題,Unity用了分離網格連接系統組件
Start:分離網格鏈接的開始點物體
End:分離網格鏈接的結束點物體
Cost Override:開銷覆蓋,如果值為正數,計算處理路徑的請求時,路徑開銷。否則,我們使用默認開銷成本(這個游戲對象所屬的層的開銷)。如果Cost Override的值設置為3.0,在分離網格的鏈接移動相同的距離的開銷,是在默認的導航網的三倍。此屬性是運行時可編輯,不需要重新烘焙。
Bi Directional:雙向定向,如果勾上這個選項,鏈接的兩個方向都可以通過,如果取消勾選的話,只能從開始點到結束點這樣的鏈接方向通過。
Activated:激活,指定這個鏈接實際上是否由尋路者使用。當此屬性為false,分離網格的鏈接將被不予理會。此屬性是實時可編輯的,不需要重新烘焙。
Auto Update Position:自動更新位置,當他們的位置移動時,連接的端點可以自動更新嗎
Navigation Layer:導航層,連接屬於哪個導航層
分離網格鏈接OffMeshLink屬性的特別注意事項
1、"Activated"和"Cost Override"的屬性可以在運行時改變,有立竿見影的效果(值一改變,馬上就產生效果)。其他所有屬性改變需要重新烘焙導航網格才會起作用。
2、在烘焙時,如果未分配開始或結束的變換(transforms)的位置,或者是跟導航網格離得太遠,而無法找到有效的位置,分離網格鏈接將不會產生。在這種情況下,在控制台窗口(Console window)中顯示一個錯誤。
3、導航網格烘焙 navmesh baking
一旦導航網格幾何體以及所屬的層被標記好,該開始烘焙導航網格幾何體
Radius:典型的代理的半徑(值越小,效果越好)
Height:典型代理的高度(所需角色通過的高度)
Max Slope:最大坡度,大於這個斜坡的面,會被丟棄
Step Height:台階的高度,高度差低於這,導航網格地區被視為連接。
Drop Height:下落高度,如果這個屬性的值是正數,相鄰的導航網格表面高度差低於此值,將進行網格連接。
Jump Height:跳躍距離,如果這個屬性的值是正數,相鄰導航網格表面的水平距離低於此值,將進行網格鏈接。
代理的半徑(Agent Radius)控制着下降連接能達到多遠,Drop Height控制着下降連接能有多長
Jump Distance(跳距離)控制 跳 - 過鏈接是如何計算出來的。注意,目的地必須在同一水平的開始。
min Region Area:最小區域面積,低於此臨界值的區域將被丟棄。
Width Inaccuracy:寬度誤差%,容許的寬度誤差(百分比)
Height inaccuracy:高度誤差%,容許的高度誤差(百分比)
Height Mesh:高度網格,如果這個選項被選上,原始高度信息會存儲起來。這對速度和內存性能有一定影響。
請注意,烘焙好的導航網格是場景的一部分,代理可以按照導航網格決定可否通過。要刪除導航網格,在烘焙選項卡(Bake )點擊清除(Clear )按鈕。
看一張圖,更容易理解:
Radius:半徑,定義代理中心能夠到達牆邊或窗台的距離
Height:高度,定義代理能夠到達多低的地方
Max Slope:最大坡度,定義代理走的坡度陡峭度
Step Height:台階高度,定義代理可以踩多高的障礙物
4、導航網格障礙物 Navmesh Obstacle
在導航網格上的固定障礙物,可以作為烘焙過程中的一部分設置。但是,也可能在場景具有動態阻擋物,這將通過Agent移動來避開。這種動態障礙物,可以指定Navmesh Obstacle組件設置,可以被添加任何游戲物體上並隨該對象移動。
Radius:障礙物圓柱的半徑
Height:障礙物圓柱的高度
Move Threshold:移動閾值
Carve:切割
5、導航網格層
尋路系統的首要任務是找到尋路空間中2點的最優路徑。在最簡單的情況下,最優路徑即最短路徑。然而,在許多復雜的環境中,某些區域很難穿越(例如,穿過一條河流比通過橋梁更加費事)。為了模擬這些情況,unity引入代價(cost)和最優路徑(optimal path)概念,即最低代價路徑。unity使用導航網格層(Navmesh Layers)來管理路徑代價。標記為靜態導航網格的所有幾何體都屬於導航網格層。
尋路過程將對可能的路徑進行代價評估,而不是進行長度比較。處理方法是對路徑長度根據導航網格層的代價進行縮放。請注意,所有代價都設置為1時,最優路徑相當於最短路徑。
為一個用戶層(user layer),設置名稱和代價值。
名稱用來在場景中標識導航網格層。代價值表示在導航網格層上移動的難易程度。默認為1(表示正常速度移動), 2表示2倍難度(表示2倍的難度移動),0.5表示為默認難度的一半。
有3個內置的層:
Default(默認)-所有沒有做特殊設置的物體的默認代價值。
NotWalkable(不可穿越)-代價值忽略
Jump(跳躍)-自動生成的分離網格的代價
將自定義的層應用到指定幾何體的步驟:編輯器中選擇幾何體 → 調出導航網格窗口(Window->Navigation Mesh) → 到Object標簽,為物體選擇你要設置的尋路層。
如果你在導航網格窗口啟用了Show NavMesh選項,在編輯器中,不同的導航網格層會顯示為不同的顏色。
如果你想讓代理組件設置哪個層不能穿越:打開幾何體的導航網格代理NavMesh Agent組件 → 更改NavMesh Walkable屬性 → 不要忘記在腳本中設置代理的終點屬性
注意:不建議把代價值設置為小於1的數值,因為這樣的話尋路算法不能保證得到最優路徑。