Unity之網(wǎng)格導(dǎo)航

前言:在游戲中經(jīng)常出現(xiàn)怪物自己會(huì)走路,人物跟隨鼠標(biāo)點(diǎn)擊位置進(jìn)行移動(dòng),那么這些功能是怎么實(shí)現(xiàn)的呢?通過(guò)本節(jié)內(nèi)容的學(xué)習(xí),你會(huì)對(duì)自動(dòng)尋路的原理有一個(gè)初步的認(rèn)識(shí)。當(dāng)然了如果想像英雄聯(lián)盟里面的人物那樣帶點(diǎn)擊的特效的話,還需要用到粒子系統(tǒng)方面的知識(shí),好了,廢話不多說(shuō)了,咱們開(kāi)始吧


1. 認(rèn)識(shí)網(wǎng)格導(dǎo)航組件

Nav Mesh Agent(網(wǎng)格導(dǎo)航代理)

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

Off Mesh Link(分離網(wǎng)格連線)

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


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

Nav Mesh Obstacle(網(wǎng)格導(dǎo)航障礙)

  • Shape:obstacle的幾何形狀,選擇物體最合適的形狀,有兩種Box方塊和Capsule膠囊體。
  • Box/Center:方塊形狀的中心點(diǎn),與Transform的Position有關(guān)。
  • Box/Size:方塊的大小尺寸。
  • Capsule/Center:膠囊體形狀的中心點(diǎn),與Transform的Position有關(guān)。
  • Capsule/Radius:膠囊體的半徑。
  • Capsule/Height:膠囊體的高度。
  • Carve:當(dāng)Carve該選項(xiàng)被勾選,Obsacle該物體會(huì)在NavMesh上制造一個(gè)空洞。
  • Move Threshold:Unity會(huì)在Obstacle移動(dòng)該距離下,將其處理為移動(dòng)狀態(tài),使用該屬性設(shè)置移動(dòng)更新Carve空洞的頻率。
  • Time To Stationary:Obstacle停止運(yùn)動(dòng)后,經(jīng)過(guò)多少時(shí)間(秒)會(huì)被處理為靜止?fàn)顟B(tài)。
  • Carve Only Stationary:?jiǎn)⒂脮r(shí),Obstacle僅會(huì)在靜止時(shí)被處理成空洞,詳見(jiàn)官方文檔(廢話)。這里有幾個(gè)小細(xì)節(jié)需要注意,禁用該選項(xiàng)時(shí),空洞的重新計(jì)算是隔一幀計(jì)算一次,就是兩幀計(jì)算一次。然后最好啟用該選項(xiàng),因?yàn)槊看慰斩吹闹匦掠?jì)算比較費(fèi)時(shí)。官方文檔中舉了兩個(gè)適用的場(chǎng)景:木桶、箱子之類會(huì)受力停止的啟用選項(xiàng),而像坦克緩慢移動(dòng)的,則可以禁用該項(xiàng)。

Navigation面板(導(dǎo)航面板)

Agents(網(wǎng)格導(dǎo)航代理)

  • Agent Types:導(dǎo)航代理類型
  • Name:導(dǎo)航代理名字
  • Radius:導(dǎo)航代理半徑
  • Height:導(dǎo)航代理高度
  • Step Height:能上去的臺(tái)階高度
  • Max Slope:最大的坡度

Areas(導(dǎo)航區(qū)域)

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

Bake(烘焙參數(shù)面板)

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

Object(物體參數(shù)面板)

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

2. 使用網(wǎng)格導(dǎo)航組件實(shí)現(xiàn)跟隨物體位置移動(dòng)

搭建環(huán)境

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

3. 烘焙導(dǎo)航網(wǎng)格

  • 打開(kāi)導(dǎo)航面板


  • 選中要烘焙的地形對(duì)象


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


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


  • 設(shè)置能夠跳躍斷層


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


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

4. 創(chuàng)建角色和跟隨物體

  • 創(chuàng)建一個(gè)膠囊體當(dāng)作小人


  • 創(chuàng)建一個(gè)Cube當(dāng)作跟隨物體


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

6. 腳本

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

//按下鼠標(biāo)左鍵玩家跟隨移動(dòng)
//掛載對(duì)象:Player游戲?qū)ο?public class Test01 : MonoBehaviour
{
    //玩家要到達(dá)的位置
    public Transform TrCube;
    //網(wǎng)格導(dǎo)航代理
    private NavMeshAgent mNMA;
    void Start()
    {
        //得到NavMeshAgent組件
        mNMA = GetComponent<NavMeshAgent>();
    }


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

參考文章:Unity3D 官方文檔 NavMesh三個(gè)組件的翻譯與解釋 自動(dòng)尋路需要知道的細(xì)節(jié)


最后:網(wǎng)格導(dǎo)航的所有內(nèi)容就到這里了,通過(guò)這篇文章咱們認(rèn)識(shí)了網(wǎng)格導(dǎo)航的三個(gè)基本組件以及導(dǎo)航面板,通過(guò)做一些小demo去加深理解,好了,這期內(nèi)容就到這里了,大家再見(jiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容