进击的新版NavMesh系统:看我飞檐走壁
0x00 前言
unity5.6作為Unity5最后的一個版本,的確起到了一個承上啟下的作用。除了上一篇文章《進(jìn)擊的AssetBundles和它的工具們》中提到的AssetBundles-Browser,本文還會介紹另一個在Github開源的,用于Unity5.6+的新尋路功能。
0x01 曾經(jīng)的痛點(diǎn)
Unity5.6之前的navmesh系統(tǒng)的確操作起來十分容易上手,門檻很低。我們只需要將場景內(nèi)需要烘焙navmesh的區(qū)域勾選上Navigation Static選項(xiàng),之后就可以在Navigation窗口中烘焙整個場景了。
但是曾經(jīng)的navmesh系統(tǒng)卻也存在著一些性能上的和使用場景上的缺陷。
一個常見的問題,由于要預(yù)先烘焙場景的navmesh,因此我們很難方便的在運(yùn)行時動態(tài)的修改navmesh。更不用說,有一些游戲的場景并非提前制作好的,需要在運(yùn)行時動態(tài)的生成,這種情況下就無法使用navmesh了。
另一個問題是,如果場景過大的話,烘焙之后的navmesh也會保存很多數(shù)據(jù),在運(yùn)行時會造成一些內(nèi)存上的開銷。
當(dāng)然,拋開這些不談,另外一個讓我吐槽navmesh的一點(diǎn)就是,它竟然不支持垂直面的導(dǎo)航。
在做一些2d的platform游戲時,我很希望能利用navmesh來實(shí)現(xiàn)尋路的邏輯。(圖文無關(guān))
但是,不幸的是,之前的navmesh是不支持的。
0x02 組件化的navmesh
不過還好,雖然新的navmesh系統(tǒng)并沒有隨著unity的正式版本一同發(fā)布。但是,我們還是可以通過github來獲取這些新的功能:
NavMeshComponents
需要注意的是,Unity的版本要求在5.6以上。
我們可以看到,其實(shí)這里只有4個高層的C#腳本文件:
利用這4個腳本文件,就能基本解決我們之前的煩惱了。
其中NavMeshSurface這個腳本將navmesh組件化,利用這個組件就可以很方便的烘焙掛載該組件的對象的navmesh信息,而無需打開一個navigation窗口對整個場景進(jìn)行烘焙了。我們甚至可以將掛載這個腳本的GameObject烘焙后保存為一個prefab,這個帶有navmesh信息的prefab跟其他的prefab一樣。
為對象添加NavMeshSurface組件很簡單。在這里我們可以看到和之前navigation窗口類似一些設(shè)置,但是請注意,這里已經(jīng)不是整個場景烘焙了。navmesh已經(jīng)組件化了,它只會烘焙掛載它的對象。
只要點(diǎn)擊一下這個組件下的Bake按鈕,掛載它的對象就被烘焙好了。
那么GameObject能否掛載多個NavMeshSurface組件呢?這一種需求也的確存在,例如怪物和玩家的尋路策略不同,有些地方玩家能通過而怪物卻不能通過。
這的確也是可以的,同一個GameObject能夠同時掛載多個NavMeshSurface組件,并且烘焙不同的navmesh供不同的角色使用。
這樣,我們針對不同的角色的NavMeshAgent組件設(shè)置不同的agent type并和烘焙好的兩個navmesh匹配好就可以了。
0x03 飛檐走壁
好了,借助NavMeshSurface組件我們實(shí)現(xiàn)了navmesh的組件化。那么是不是我們就能很方便的實(shí)現(xiàn)在垂直面上烘焙navmesh了呢?各位想想我們是否能很輕松的讓一個游戲?qū)ο蟮慕嵌雀淖兡?#xff1f;答案是是的。那么這個游戲?qū)ο笊先绻衝avmesh信息的話,我們只需要把這個游戲?qū)ο髲乃阶優(yōu)榇怪笔欠窬托辛四?#xff1f;是的。
因此實(shí)現(xiàn)游戲角色的在垂直面上飛檐走壁的功能就變得十分簡單了。
當(dāng)然了,在水平面的navmesh和垂直面的navmesh之間我們還會用到NavMeshLink這個組件來鏈接二者。各位自己在實(shí)踐的時候需要留意一下這一點(diǎn)。
0x04 在運(yùn)行時烘焙navmesh
接下來就讓我們看看新的navmesh系統(tǒng)帶給我們的新的驚喜——在運(yùn)行時烘焙navmesh。
這是一個很現(xiàn)實(shí)的需求,例如一些動態(tài)生成場景的游戲,我們無法在一開始就確定這個場景到底是什么樣子的,所以也無法使用之前的navmesh系統(tǒng),因?yàn)橐郧暗膎avmesh只能在editor內(nèi)烘焙。但是現(xiàn)在我們使用新的navmesh系統(tǒng)就能夠很方便的在運(yùn)行時烘焙navmesh了。
如圖,這是一個空場景,在游戲運(yùn)行之后場景才生成出來場景內(nèi)的各種道路,此時單擊鼠標(biāo),navmesh就生成了。
其實(shí)在新的navmesh系統(tǒng)內(nèi),實(shí)現(xiàn)這個機(jī)制十分簡單。只需要調(diào)用游戲?qū)ο笊蠏斓腘avMeshSurface組件的BuildNavMesh()方法。
既然navmesh已經(jīng)可以在運(yùn)行時創(chuàng)建了,那么我們能否也在運(yùn)行時實(shí)例化一個navmesh的prefab,實(shí)時的影響場景內(nèi)的尋路策略呢?
答案是當(dāng)然可以。
0x05 場景太大不用愁
自己做過尋路算法的童靴可能會意識到一個問題,就是在做尋路時如果場景過大的話,尋路的數(shù)據(jù)可能會比較消耗內(nèi)存。同樣在navmesh中,如果場景過大,或者玩家的視野范圍有限,一些對玩家當(dāng)前位置影響不大的場景的其他位置的navmesh數(shù)據(jù)就有可能造成一些無謂的消耗。
在新的navmesh系統(tǒng)中,我們同樣可以優(yōu)化這個問題,只烘焙玩家周圍的navmesh。
這里同樣需要NavMeshSurface組件,在inspector視窗我們可以選擇collect object中的volume,之后設(shè)定size的值就可以值烘焙這個范圍內(nèi)的navmesh了。之后隨著玩家的移動,再動態(tài)烘焙新的navmesh就可以了。
ref:
【1】High-level NavMesh Building Components
【2】Unite Europe 2017 - Finding the path: New navigation features
各位如果覺得有趣的話,歡迎點(diǎn)個贊。
-EOF-
最后打個廣告,歡迎支持我的書《Unity 3D腳本編程》
歡迎大家關(guān)注我的公眾號慕容的游戲編程:chenjd01
轉(zhuǎn)載于:https://www.cnblogs.com/murongxiaopifu/p/7196788.html
總結(jié)
以上是生活随笔為你收集整理的进击的新版NavMesh系统:看我飞檐走壁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: winform 基础
- 下一篇: Makefile的伪目标