Untiy 提供 NavMesh (導(dǎo)航網(wǎng)格)可使物體實(shí)現(xiàn)自動(dòng)尋路?!?Unity 人工智能游戲開(kāi)發(fā)》在第四章介紹了 NavMesh ,里面提供的示例蠻有趣的。使用 NavMesh 涉及很多界面設(shè)置操作,于是寫(xiě)篇筆記記錄一下。
運(yùn)行截圖
示例在 Unity5.5 中運(yùn)行。完整代碼在 UnityResource/Book-UnityAIGameProgramming/Assets/Chapter4 目錄中。
- NavMesh 基本使用

- NavMesh 斜坡測(cè)試

- NavMesh 區(qū)域探索

- NavMesh OffMeshLinks

初探筆記
如果代碼下載下來(lái)后導(dǎo)航網(wǎng)格不能正常使用,可以先清除之前的烘培數(shù)據(jù)再重新烘培。
基本使用 - NavMesh01_Simple
■ 標(biāo)記一些靜態(tài)物體為 Navigation Static 。如標(biāo)記平面 plane 。可以直接在 Inspector 面板上設(shè)置。也可以在 Window|Navigation|Object 選項(xiàng)卡下,選中 plane 并勾選 Navigation Static 。


■ 為需要尋路的物體添加 NavMeshAgent 組件,并設(shè)置適當(dāng)?shù)膮?shù)。一般需要設(shè)置物體的半徑、高度、速度、加速度、距離目標(biāo)的停止距離。

■ 烘培前,在 Window|Navigation|Bake 選項(xiàng)卡下設(shè)置 Agent 參數(shù)。一般需要設(shè)置 Agent 的半徑、高度、可以行走的最大斜坡角度、可以越過(guò)的高度。

■ 在 Window|Nagivation 窗口中點(diǎn)擊按鈕 Bake 進(jìn)行烘培。按鈕文字重新變成 Bake 表示烘培完成,此時(shí)會(huì)生成 NavMesh.asset 文件。
■ 設(shè)置完成后編寫(xiě)腳本進(jìn)行導(dǎo)航。獲取 NavMeshAgent 組件,然后調(diào)用 NavMeshAgent.SetDestination 函數(shù)設(shè)置導(dǎo)航的目標(biāo)位置,物體便會(huì)自動(dòng)尋路到達(dá)目的地。
■ 注意如果 Window|Navigation|Bake 選項(xiàng)卡下,半徑、高度、步高參數(shù)設(shè)置不適當(dāng)會(huì)可能導(dǎo)致無(wú)法創(chuàng)建 NavMesh 或者 NavMeshAgent 無(wú)法通過(guò)斜坡。
比如 NavMesh02_Slope.unity 示例中,我之前依次按照 0.5 2 45 0.4 參數(shù)設(shè)置進(jìn)行烘培,坦克無(wú)法穿過(guò)斜坡。這個(gè)場(chǎng)景中坦克的縮放是 (1, 1, 1) 。之后改成 22 15 45 12 進(jìn)行設(shè)置就正常了。
比如 TDSample.unity 中,坦克的縮放是 (0.05, 0.05, 0.05) 我按照 22 15 45 12 參數(shù)設(shè)置進(jìn)行烘培無(wú)法生成 NavMesh ,后來(lái)改成 0.5 2 45 0.4 設(shè)置后就烘培成功了。
坦克模型的設(shè)置中, Scale Factor 是 100 而 FileScale 是 0.01 。而 NavMesh01_Simple.unity 示例中,坦克的縮放是 (1, 1, 1) 而烘培參數(shù)是 0.5 2 45 0.4 。所以我還沒(méi)有完全搞明白烘培界面上的參數(shù)與 NavMeshAgent 組件上的參數(shù)和物體的大小有什么確切的關(guān)系。但是烘培不成功又沒(méi)有提示,這是最氣的。
斜坡測(cè)試 - NavMesh02_Slope
斜坡角度在 Agent 可以同行的范圍內(nèi)時(shí),便可以通過(guò)斜坡。 要留意 Window|Navigation|Bake 選項(xiàng)卡下的 Max Slope 設(shè)置。還要注意斜坡和平面要完美連接,不要有間隙,存在間隙時(shí) Agent 無(wú)法通過(guò)也就無(wú)法獲取有效的路徑。
區(qū)域探索 - NavMesh03_Layers
當(dāng)游戲環(huán)境復(fù)雜時(shí),比如前方有湖面和橋梁,希望對(duì)象能優(yōu)先通過(guò)橋梁。此時(shí)就可以把通過(guò)湖面的估值(cost)設(shè)置更高。具體表現(xiàn)為在 Window|Navigation|Areas 添加新的區(qū)域 Water 并設(shè)置 Cost 為 5 。

然后選中湖面物體并設(shè)置 Navigation Area 為 Water 。重新烘培以使設(shè)置生效。

設(shè)置 Off Mesh Links
■ 某些時(shí)候,場(chǎng)景之間可能存在縫隙,使得導(dǎo)航網(wǎng)格處于非連接狀態(tài)。如下圖場(chǎng)景中的兩個(gè)非連接平面(烘培后的 NavMesh)。這樣,Agent 就無(wú)法通過(guò)間隙,在這兩個(gè)平面來(lái)回移動(dòng)。然而,OffMeshLinks 就提供特性用于連接此類間隙。 OffMeshLinks 可以通過(guò) OffMeshLink 組件手動(dòng)創(chuàng)建,也可以在 Window|Navigation|Object 為物體勾選 Generate OffMeshLinks 自動(dòng)在烘培時(shí)創(chuàng)建。

■ 無(wú)論是通過(guò)自動(dòng)還是手動(dòng)方式創(chuàng)建 NavMeshLinks 都需要設(shè)置在 Window|Navigation|Bake 選項(xiàng)卡設(shè)置 Jump Distance ,間隙的距離小于此值才可以被連接。

★ 自動(dòng)創(chuàng)建 OffMeshLinks
在 Window|Navigation|Object 選項(xiàng)卡,為物體勾選 Generate OffMeshLinks 這樣在烘培時(shí)就可以自動(dòng)產(chǎn)生了。假設(shè) PlaneA 設(shè)置了 OffMeshLinks 而 PlaneB 沒(méi)有,此時(shí)物體可以從 PlaneA 移動(dòng)到 PlaneB 而不能從 PlaneB 移動(dòng)到 PlaneA 。

設(shè)置完成后烘培會(huì)產(chǎn)生如下效果,產(chǎn)生了兩個(gè)平面的連接線。

★ 手動(dòng)創(chuàng)建 OffMeshLinks
手動(dòng)創(chuàng)建類似于傳送門(mén),雙方通過(guò)此傳送門(mén)物體連接。選擇一個(gè)傳送門(mén)物體并添加 OffMeshLink 組件。將一個(gè)物體設(shè)置到 Start 屬性中,另一個(gè)設(shè)置到 End 屬性中。

設(shè)置完成后烘培,會(huì)產(chǎn)生如下效果。圖中的四條線把兩個(gè)平面連接起來(lái)了。
