Navigation Static:不會移動。可以用於計算可行走區域。例如:地板。牆。靜態障礙物。
將一個物體選為Navigation Static:Navigation窗口-> 勾選項
Scene Filter 選中 All:表示 Hierarchy 視圖中顯示全部的 GameObject
Scene Filter 選中 Mesh Renderers:表示 Hierarchy 視圖中只顯示有 Mesh Renderer 的 GameObject
選中 Navigation Static:表示 Bake 時會將這個物體考慮進去
可以參考以下文章:
http://blog.csdn.net/janeky/article/details/17492531
《Top-Down RPG Starter Kit》示例程序
他是 Asset Store 的一個 demo,實現了點擊路面走路,但是他並沒有尋路,點擊路面后,他只能直線走,遇到障礙就停下來了。
他使用的是 CharacterController。這個組件可以幫你處理 Collider,讓你不會和障礙物相交。
關於導航網格的一些疑問:
http://forum.unity3d.com/threads/navmesh-heightmesh-questions.117083/
靜態障礙物
是在 Bake 時指定的。方法:場景中選中某個物件 -> Navigation Window 的 Object 標簽頁 -> 勾選 Navigation Static -> Navigation Layer 選擇 Not Walkable
可以看到物體所在的區域在 Bake 之后被排除掉了:
動態障礙物
不是在 Bake 時指定的。而是通過給物體加一個 Nav Mesh Obstacle 組件生成的。
動態障礙物可分為2種:
一種是沒有勾選 Carve。尋路時計算路徑並不會考慮到他。是到他周圍了才會去繞過他。
一種是勾選 Carve。會重新導航網格的區域。計算路徑時就會把他考慮進去,計算出來的路徑就不會和他沖突。會有性能損失。
關於這2種可以在以下鏈接找到詳細描述:
http://docs.unity3d.com/ScriptReference/NavMeshObstacle.html
例子:
球:要移動的物體
立方體:障礙物,Carve沒有打勾 (可以看到導航網格並沒有繞過他,而是包含他)
圓柱體:球要移動到這個位置
綠色箭頭:如果沒有障礙物的情況下球應該走的路線
移動結果:
關於 NavMeshPathStatus
PathComplete The path terminates at the destination.
使用 NavMesh.CaculatePath 函數時,如果目標點與導航網格的距離在合適的范圍內(這個還要研究一下),並且能找到一條路徑到達目標點時,就會是這個狀態;
PathPartial The path cannot reach the destination.
使用 NavMesh.CaculatePath 函數時,如果目標點與導航網格的距離在合適的范圍內(這個還要研究一下),但是目標點無法到達時,會是這個狀態;
PathInvalid The path is invalid.
使用 NavMesh.CaculatePath 函數時,如果目標點與導航網格的距離不在合適的范圍內(這個還要研究一下),那么就是這個狀態;
尋路方案選擇!!!
(1) | (2) | (3) | (4) | |
Navigation Static | × |
√ |
√ |
× |
Default | × |
√ |
× |
× |
Not Walkable | × |
× |
√ |
× |
Nav Mesh Obstacle (Carve = false) |
× |
× |
× |
√ |
每種情況的效果:
情況(1):物件在生成導航網格時完全被忽略。agent尋路時也完全忽略他,直接從他身上穿過去。
情況(2):將參與導航網格生成。如果是一個形狀類似於Cube的東西,而高度 > Step Height,那么他跟 Not Walkable 是差不多的。如果是一個類似於Cube的東西,而高度 < Step Height,會形成一個坡,從他上面跨過去。但如果不是像 Cube,而是一個任意形狀,你又希望他會成為障礙物,那么就算他很高也不要選擇使用 (2)。
情況(3):生成障礙區域,生成導航網格時會摳掉這些區域。
情況(4):就是一個障礙物,注意這里Carve是設置為false。agent 尋路時會自動繞過他(尋路時是不會考慮他的,也就是說尋路后的路線可能穿過他,在靠近他的時候會動態地繞開他)。
方案:
情況(1):完全不在導航范圍內的物體使用這個。比如遠處的山,山上可能有樹啥的,都使用這種。這個跟地圖分塊有關。
情況(2):在導航范圍內的,角色能夠到達的區域使用這個。比如地板。
情況(3):在導航范圍內的靜態障礙物使用這個。
情況(4):用於其他玩家及NPC(包括怪物)。屬於動態障礙物。他們的 NavMeshObstacle 組件是放在 Prefab 中的,提前就設定好的。
主角:使用情況(1)。身上綁定一個 NavMeshAgent。他在尋路的過程中,自然就會繞過其他玩家和NPC。只有主角使用應該不會很耗吧?
這篇文章說明了 Unity 的 Nav Mesh 遇到障礙時並不會智能地繞過(障礙沒有勾選 Carve,或者是繞過其他 agent 時):
但是他推薦了另一個可以用的庫(方案好像就是跟勾選 Carve 一樣的):
http://answers.unity3d.com/questions/396867/getting-navmeshagents-to-avoid-obstacles-effective.html
agent既會繞過其他agent,avoidance priority 越低表示優先級越高,優先級越高的會‘推’優先級越低的。這個‘推’表現不太好,也沒有解決方案。
如果說除了主角以外,其他玩家和NPC都用 Obstacle ,首先 Obstacle Carve 不能是 true,(猜的),因為會很卡。
如果 Carve = false,那么實際上不能動態尋路。agent在查找路線的時候是不會考慮這些 Carve=false的 Obstacle 的,導致他碰到這些障礙物時,根本不會繞彎,很容易卡住。
asset store 上面有一款 <Dynamic Navigation> ,不知道能不能解決問題。
或者是 <A* Pathfinding Project Pro>
尋路需求:
主角 | 客戶端計算尋路 |
功能NPC | 通常不動 |
怪物和尋路NPC | 由服務器計算尋路,然后同步給客戶端 |
其他玩家 | 由他自己的客戶端計算尋路,發給服務器,服務器再同步給客戶端 |
主角靜態尋路
主角動態尋路:進行靜態尋路的過程中,如果被怪物或其他玩家阻擋,則必須要重新計算路徑。不可以‘推動’怪物或其他玩家。