1. 程式人生 > >unity 2種實現動態障礙方法

unity 2種實現動態障礙方法

必須 tar 模糊 ont 支持 獨立 com new bst

此文將介紹2種實現動態障礙的方法,一種基於navmesh,一種基於astar算法。

1.基於navmesh。

  1.制作場景障礙:

    a.有幾個獨立的障礙物,就定義幾個user area,即,一個場景僅僅支持一個字節數目的獨立障礙物

      技術分享

    b.建立碰撞盒建立障礙物:

      碰撞盒是可行走區域。

      技術分享

    c.設置碰撞盒gameobject的navigation面板的object頁簽的navigation area屬性:

      每個獨立障礙物對應一個前面步驟a中定義的area,如果幾個障礙一起動態生成或消失,則可以使用同一個area

      技術分享

  2.代碼控制這些動態障礙物的生成和消失:

    障礙物消失是它的碰撞盒區域加入navmesh尋路mask中,即障礙物區域可行走,生成是不加入mask中,該區域不可行走

開啟或關閉第幾個door:
_door += 2;//因為前面有3個內置area:walkable,not walkable和jump,假如_door=1,即_door+=2後_door=3, 下面的1<<3後1在右起第4個字節,即對於第4個area:door1 if (_flag > 0)//flag>0表示開門,即障礙物消失,該碰撞盒區域可行走,需把該area位 置為1 { navmesh_mask_ |= (1 << _door); }
else { navmesh_mask_ &= (~(1 << _door));//該area位 置為0 }

  3.真正用到的地方(上面所有的工作服務的對象,其實也是此動態障礙解決方法的思考起點,我就是想知道CalculatePath的第3個參數的作用才找到此解決方法的):

    所謂障礙物,影響的就是尋路!當障礙物消失時我們需要讓此區域可行走,沒消失時不可行走,下面是尋路代碼:

NavMeshPath nav_path = new NavMeshPath();
if (NavMesh.CalculatePath(src_pos, dis_pos, navmesh_mask_, nav_path))

    即,通過控制calculatepath的第3個參數navmesh_mask實現動態障礙的控制:navmesh_mask每個位對應一個area,當某個area對應的位是0時尋路認為不可行走,1則可行走。

  總結:此方法簡單明了,並且navmesh功能是官方提供的,性能方面占優。但這個動態障礙物必須是預先擺好的,不能像lol中亞索的盾牌那樣“隨意區域”動態,不過一般這種假動態就已經足夠項目使用了。

   看來要繼續研讀navmesh文檔,看官方有沒有提供解決真動態障礙的方案了。

  更新更新:打臉了,打臉了,用NavMesh Obstacle組件就能輕易讓一個gameobject變成障礙物並重新計算尋路網格,這個好啊,是真動態!明天測試一下。

2.基於astar,動態障礙物狀態更新時,都需要重新計算“可行走”網格,即把障礙物所在區域改成可行走,重新設置整個網格的“可行走”區域,讓尋路變得正確。這個astar插件已經基本做好了,讀者可以查閱其文檔即可。

  總結:此方法應該能解決隨地生成動態障礙和去除動態障礙問題,就是不知道性能怎麽樣,好像計算量蠻大的,有空看看。PS:其實之前我看過重構可行走區域的相關代碼了,但年久模糊,回頭復習後再補全此部分。

unity 2種實現動態障礙方法