日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

unity 4种实现动态障碍方法

發布時間:2024/1/17 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unity 4种实现动态障碍方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

此文將介紹4種實現動態障礙的方法,2種基于navmesh,2種基于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變成障礙物并重新計算尋路網格,這個好啊,是真動態!明天測試一下。

  再次更新再次更新:因為使用navmesh_mask的方式不需要重構尋路網格,所以性能很好,所以把navmesh_mask和navmesh obstacle結合起來使用:

        固定位置的動態障礙物使用navmesh_mask,不固定位置的動態障礙物使用navmesh obstacle,這樣也不算打臉了=。=

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

  大致說一下2種解決方法:

    1.astar的動態障礙物實例腳本是這樣的:一個帶collider的gameobject,每次移動都調用一下:

      AstarPath.active.UpdateGraphs(oldbounds);AstarPath.active.UpdateGraphs(newbounds);//oldbounds表示舊位置的bounds,new表示新位置的包圍盒立方體

      其實就是刷新一下網格某個區域,對這個區域的每個網點檢測:如果被帶collider的物體占,則不可行走,否則可行走。這明顯可以解決隨意位置動態障礙問題,并且用法簡單,可以考慮。

    2.還有另外一種方法,也是我目前項目使用的:不依賴collider,直接輸入一個bounds,然后把這個bounds和整個網格相交,得到需要更新的bounds區域,然后直接對整個區域的網點node進行設置是否可行走:

GridGraph mGridGraph=null; NavGraph[] graphs = AstarPath.active.graphs; for(...) {if (graphs[i] is GridGraph){mGridGraph = graphs[i] as GridGraph;break;} } ...//計算需要設置的網點外殼 mGridGraph.nodes[z * mGridGraph.width+x].Walkable = pWalkAble;

本文總結:本文基于navmesh給出了2種解決方法,實際應用時可以結合起來提高性能,基于astar也提出了2種解決方法。

轉載于:https://www.cnblogs.com/Tearix/p/6919439.html

總結

以上是生活随笔為你收集整理的unity 4种实现动态障碍方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。