NavMeshを初めてやってみました。予め経路探索をやっておいて、実行時に最短経路で移動させられる仕組みです。
動かせる障害物を設定できるようで、これを使うと動的に変化する環境を実現できるのでやってみようと思いました。
こちらの記事を参考にさせてもらいました。
tsubakit1.hateblo.jp
段取りとしては、まずマップを作ります。壁や床には、Inspector右上のstaticにチェックを入れておきます。
環境ができたら、Windowメニューから、navigationを選ぶとNavMeshの設定画面が出ます。Bakeタブを選びます。Bakeボタンを押すと移動できる場所、移動できない場所を判断してメッシュが出来上がります。
経路のBake前
経路のBake後
NavMeshの中を動かしたいエージェントには、コンポーネントでNavMeshAgentをAddします。
スクリプトとしては、ゴールをSetDestinationで設定します。
静的に探索済みの経路の中から最短経路でキャラクターが移動を初めます。
NavMeshAgent agent; void Start () { agent = GetComponent<NavMeshAgent>(); agent.SetDestination(target.position); }
次に実行時に動的に経路を変えたい場合。
例えばドアが開閉したり。
そういう場合はstaticチェックせずに、物体にNavMeshObstacleをコンポーネントADDします。Carveにチェックをいれます。
先程の経路探索Bake時には、通れない物体として扱われます。しかし、実行時に動かせばそこは通れる経路と扱われます。
具体的な例ですが、ドアを2つつけた塀があります。
元々は左は空いているので、エージェントは左に向います。実行時に障害物を動かせるので、動かすと通せんぼができます。今度は空いた右のドアの方にエージェントは向かいます。カーナビで車で走っている時に道を間違えると経路探索が自動で走って、再度新しい経路が設定されるのと似たような感じです。
例えば、NavMeshObstacleなGameObjectに以下のようなコードをAddしておけば動的に動かせます。
void Update () { float ay = Input.GetAxisRaw("Horizontal"); transform.position -= new Vector3(ay,0,0) * Time.deltaTime * 10f; }
できてみればコード追加も少しでできましたが、迷ったのは、壁にもNavMeshAgentをすべてAddするのかと思いました。壁や床はstaticチェックするだけです。Addが必要なのは経路内を移動させたいGameObjectだけです。
© Unity Technologies Japan/UCL