Unityの経路探索: NavMeshとAgentとObstacle

(2017-06-29)

NavMeshというのはエージェントが移動できる面についてのデータ構造で、凸ポリゴンの面と位置関係を含んでいる。 経路探索は2点間を一番近いポリゴンにマッピングし、A*アルゴリズムを用いて行われる。あとからオブジェクトが追加されるなどして道を塞いでしまってもCarvingしてNavMeshに穴をあければ別の経路で移動することができるが、このようなグローバルの経路探索に影響を及ぼす操作は計算にコストがかかるので、各エージェントローカルの衝突回避で済むならそのほうがよい。

こんな感じで床に適当なオブジェクトを置いてみた。

stage

階層

Window -> NavigationでBakeするのを選択してNavigation Staticし(StaticになってBakeの対象になる)、 Bakeボタンを押すとこんな感じでBakeされる。

bake

オブジェクトの上がNavMeshに含まれていないのはAgent sizeのStep Heightよりも高いため。 段差を移動するときに浮いてしまうのを避けるためにはAdvancedのHeight Meshをオンにする。 また、端が含まれていないのはこのAgentの中心が入れる位置を表しているためで、 Agent Radiusを変更すると広がったり狭まったりするのを確認できる。

Agent size

Radius0.5, Height2のCylindarを作成し、Nav Mesh Agentを追加する。

NavMesh Agent

で、ゴールにオブジェクトを置いてそこまで移動させてみる。

using UnityEngine.AI;

public GameObject goal;

void Start () {
    var agent = GetComponent<NavMeshAgent>();
    agent.destination = goal.transform.position;
}

ゴールまでたどり着くNavMesh Agent

障害物。上で通った経路上にNavMesh Obstacleを追加したCubeを置いたところうまく避けてゴールまでたどり着いた。

Obstacleを置いた

ただ、完全に道をふさいでしまうと立ち往生してしまうので Carveにチェックを入れるとCarvingされ、他の経路でゴールまで進むようになる。

Carvingした

Unityで動的にNavMeshを生成する - sambaiz-net