Unity之網格導航

前言:在游戲中經常出現怪物自己會走路,人物跟隨鼠標點擊位置進行移動,那么這些功能是怎么實現的呢?通過本節內容的學習,你會對自動尋路的原理有一個初步的認識。當然了如果想像英雄聯盟里面的人物那樣帶點擊的特效的話,還需要用到粒子系統方面的知識,好了,廢話不多說了,咱們開始吧


1. 認識網格導航組件

Nav Mesh Agent(網格導航代理)

  • Radius:agent的半徑,用于計算該agent和其他agent、obstacle的碰撞。
  • Height:agent的高度,agent可以通過的頭頂障礙最小高度。
  • Base offset:agent圓柱碰撞體中心點的偏移值。當Agent創建后,圓柱碰撞體顯示過高或過低,用于將其調整到地面。
  • Speed:agent移動的最大速度(世界空間中以秒單位計算)
  • Angular Speed:agent最大的旋轉速度(角度每秒)
  • Acceleration:agent最大的加速度(世界空間單位每秒的平方)
  • Stopping distance:agent靠近目標時停下的距離
  • Auto Braking:自動剎車,當啟用的時候agent會在到達終點時慢慢停下,你應該在角色需要平滑地巡邏幾個固定點時,禁用它。
  • Quality:障礙回避的質量值,如果你有大量的agent就可以降低該值節約CPU的資源,將它設置為0,則只會處理碰撞,不會嘗試規避其他agent和obstacle。
  • Priority:agent會重視該值比自己小的,而忽略該值比自己大的。該值范圍為0到99,數字越低意味著高權限,權限越高(越小的值)會被其他agent重視而回避。
  • Auto Traverse OffMesh Link:需要agent自動通過off-mesh link的時候設置為true,當想要使用動畫或其他特殊的方法通過off-mesh link時設為false。
  • Auto Repath:啟用時,agent會在到達局部路徑的終點時,嘗試再次尋找路徑。當沒有通向目標的路徑時,它會生成一個離目標最近的點作為當前的一個目標。(我嘗試下來發現,當目標點不可達,勾選該選項的agent嘗試尋找臨近目標點的欲望比不勾選的要大)
  • Area Mask:AreaMask描述了agent會在哪些烘培的區域中尋找路徑。當你準備烘培NavMesh時,你可以指定區域的類型,比如你想讓階梯作為一個特殊的區域,并且禁止某些角色使用階梯。
在使用Agent的時候,大家可能發現了Agent有Radius屬性,在我們烘培NavMesh的時候設置的圓柱體也有Radius屬性,兩者有什么區別呢?
在尋路的時候有兩個階段,第一階段只考慮烘培NavMesh并尋找一條可行的路徑,而第二階段Agent就已經在前往目的地的路上了,它會考慮其他agent和obstacle,并盡量避開他們。
烘培時候的Radius就對應第一階段的生成NavMesh,而Agent上的Radius只在第二階段使用。就比如說,有一條小徑,你有一只大怪是通過不了該路徑的,但烘培時候的Radius設置的比較小,雖然Agent的Radius可能設置的很大,但這只大怪還是會使用該小徑通過。
所以要理解尋路的兩個階段,再強調一遍,第一階段沒有開始真正的尋路不考慮其他的agent和obstacle,只看NavMesh,而第二階段Agent已經在行走,而會盡量避開其他agent和obstacle。

Off Mesh Link(分離網格連線)

OffMeshLink組件允許你在區域中給Agent提供一些小近路,使Agent能快速通過,比如跳過柵欄、通過一扇門。


  • Start:物體描述的開始點。
  • End:物體描述的結束點。
  • Cost Override:如果該值是正的,使用它在處理需求路徑時計算路徑的代價值,否則會使用默認的代價值(游戲物體所屬區域的代價值)。如果代價值設置超過3.0,經過該off-mesh link會比經過三倍的默認NavMesh區域還多。當你想用Agent初始化偏愛的路徑時,該代價值非常有用。當然最好是在移動中清晰比較長的距離中使用。
  • Bi Directional:如果啟用,則該link是雙向的,否則只能從Start到End。
  • Activated:指定該link會不會在尋路的時候使用(在設置為false的時候被忽略)
  • Auto Update Position:啟用的時候,Off-Mesh Link會自動重新連接start和end的坐標,如果禁用,則只使用啟用時候的坐標,即使后來坐標移動了也不會改變。
  • Navigation Area:描述link所屬的NavMesh區域類型,該區域類型會允許你在相似類型區域中應用該區域的通路代價值,并且防止一些特定的Agent使用該通路,使用Agent的AreaMask屬性來控制。

Nav Mesh Obstacle(網格導航障礙)

  • Shape:obstacle的幾何形狀,選擇物體最合適的形狀,有兩種Box方塊和Capsule膠囊體。
  • Box/Center:方塊形狀的中心點,與Transform的Position有關。
  • Box/Size:方塊的大小尺寸。
  • Capsule/Center:膠囊體形狀的中心點,與Transform的Position有關。
  • Capsule/Radius:膠囊體的半徑。
  • Capsule/Height:膠囊體的高度。
  • Carve:當Carve該選項被勾選,Obsacle該物體會在NavMesh上制造一個空洞。
  • Move Threshold:Unity會在Obstacle移動該距離下,將其處理為移動狀態,使用該屬性設置移動更新Carve空洞的頻率。
  • Time To Stationary:Obstacle停止運動后,經過多少時間(秒)會被處理為靜止狀態。
  • Carve Only Stationary:啟用時,Obstacle僅會在靜止時被處理成空洞,詳見官方文檔(廢話)。這里有幾個小細節需要注意,禁用該選項時,空洞的重新計算是隔一幀計算一次,就是兩幀計算一次。然后最好啟用該選項,因為每次空洞的重新計算比較費時。官方文檔中舉了兩個適用的場景:木桶、箱子之類會受力停止的啟用選項,而像坦克緩慢移動的,則可以禁用該項。

Navigation面板(導航面板)

Agents(網格導航代理)

  • Agent Types:導航代理類型
  • Name:導航代理名字
  • Radius:導航代理半徑
  • Height:導航代理高度
  • Step Height:能上去的臺階高度
  • Max Slope:最大的坡度

Areas(導航區域)

  • 前三個是Unity內置的Walkable(能走的),Not Walkable(不能走的),Jump(跳)
  • 其他的用戶用來自定義

Bake(烘焙參數面板)

  • Radius:具有代表性的物體半徑,半徑越小生成的網格面積越大。
  • Height:具有代表性的物體的高度。
  • Max Slope:斜坡的坡度。
  • Ste Height:臺階高度。
  • Drop Height:允許最大的下落距離。
  • Jump Distance:允許最大的跳躍距離。
  • Min Region Area:網格面積小于該值則不生成導航網格。
  • Width Inaccuracy:允許最大寬度的誤差。
  • Height Inaccuracy:允許最大高度的誤差。
  • Height Mesh:勾選后會保存高度信息,同時會消耗一些性能和存儲空間。

Object(物體參數面板)

  • Navigation Static:勾選后表示該對象參與導航網格的烘培。
  • OffMeshLink Generation:勾選后可跳躍(Jump)導航網格和下落(Drop)。
  • Navigation Area:可以導航的區域

2. 使用網格導航組件實現跟隨物體位置移動

搭建環境

  • 平面障礙物
  • 使用Off Mesh Link制作的路徑
  • 樓梯
  • 斜坡
  • 斷層
  • 洞口

3. 烘焙導航網格

  • 打開導航面板


  • 選中要烘焙的地形對象


    • Navigation>>Object>>All,Navigation Static勾選


    • Navigation>>Bake
      • 調整半徑讓其盡可能多的包含地形對象
      • 調整高度(可以進入洞口)
      • 調整最大坡度(可以上的坡度)
      • 調整臺階高度(可以走上樓梯)
      • 調整下落高度(可以從高出落下)
      • 調整跳的距離(可以跳過斷層)
      • 點擊Bake
  • 烘焙之后Scene視圖中的效果,所有顯示藍色的網格是可以導航到的位置


  • 設置能夠跳躍斷層


    • 選中能夠跳躍的對象,Navigation>>Object>>All>>Generate OffMeshLinks勾選,然后進入Bake面點擊Bake
  • 烘焙之后Scene視圖中的效果,Plane出現了箭頭指向了另一頭的Plane


  • 使用Off Mesh Link制作的路徑
    • 創建一個Cube放在第一個Plane的邊緣,克隆一個放在第二個Plane的邊緣
    • 在第一個Cube身上添加Off Mesh Link組件,把第一個Cube拖到組件的Start中,把第二個Cube拖到組件的End中,這樣就可以從第一個Plane的第一個Cube的位置到第二個Plane的第二個Cube的位置;中間的黑線就是Off Mesh Link制作的路徑

4. 創建角色和跟隨物體

  • 創建一個膠囊體當作小人


  • 創建一個Cube當作跟隨物體


5. 在角色身上添加Navigation Mesh Agent組件

6. 腳本

  • 功能:讓角色導航到跟隨物體的位置
  • 把腳本掛載到角色身上
  • 把跟隨物體拖到腳本的實例對象上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//人工智能的命名空間

//按下鼠標左鍵玩家跟隨移動
//掛載對象:Player游戲對象
public class Test01 : MonoBehaviour
{
    //玩家要到達的位置
    public Transform TrCube;
    //網格導航代理
    private NavMeshAgent mNMA;
    void Start()
    {
        //得到NavMeshAgent組件
        mNMA = GetComponent<NavMeshAgent>();
    }


    void Update()
    {
        //到指定的位置(終點的位置)
        //方法一:通過屬性
        mNMA.destination = TrCube.position; 
        //方法二:通過方法
        //mNMA.SetDestination(TrCube.position);
    }
}

參考文章:Unity3D 官方文檔 NavMesh三個組件的翻譯與解釋 自動尋路需要知道的細節


最后:網格導航的所有內容就到這里了,通過這篇文章咱們認識了網格導航的三個基本組件以及導航面板,通過做一些小demo去加深理解,好了,這期內容就到這里了,大家再見

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。