[Unity]ナビメッシュでの経路探索の使い方と注意点

Unity で簡単に経路探索を実装するにはナビメッシュが便利です。

今回は、基本的な使い方と、使ってみた上での注意点などを書いていきます。

基本

ナビメッシュを使うと、こんな感じで障害物を避けて目的地まで移動させることができます。


(日本語マニュアル)
ナビメッシュおよび経路探索 - Unity Manual

(英語マニュアル)
Unity - Navigation Meshes

現時点で日本語マニュアル(ちょっと古い?)には Pro のみと書いてありますが、英語マニュアルには書いていないので使えるみたいです。

(多分。英語でもページによって Pro only と書いてあったりします。 Unity - Pathfinding とか Unity - NavMesh Layers とか。Free 版での動作は未確認。)


とりあえず移動させるだけなら
  1. シーンに床や障害物を置く
  2. それらを Navigation Static にする(インスペクタ右上。Static チェックで OK、下三角マークで詳細)
  3. メニュー -> Window -> Navigation -> Bake タブ -> Bake ボタンで通れる場所を焼き込み
  4. 移動させたいオブジェクトに NavMeshAgent コンポーネントをつける
  5. 自前のスクリプトで、移動させたいオブジェクトの NavMeshAgent を取得して目的地を SetDestination で指定する
と簡単です。



さらに、
といったこともできます。

注意点

ここから注意点などです。

  • 微調整が効かない
    • Bake したナビメッシュ自体の手動調整はできません
    • Bake 時の設定やナビメッシュレイヤー、Navigation Static のオンオフ、果てはオブジェクト自体の位置を微調整して Bake を繰り返すことになります

  • 微妙に浮く
    • 下の画像のように、焼き込んだナビメッシュが床から離れることがあります
    • おそらく壁や手すりが悪さをしているのだと思いますが、原因不明です(上のモデルは床、壁、手すりが一体化していて分割できない)
    • Bake 時の radius (エージェントと壁までの距離) を小さくするとより顕著に起きるようにも見えましたが、本当の原因かどうかはわかりません
    • エージェントは物理無視でナビメッシュに沿って移動するため、当然床から浮きます。ちなみに、この状態でエージェントを重力で落としてみましたが上下に震動してダメでした

  • メッシュを分割しておく
    • たとえば床と壁が一体化していると、調整時に非常に困ります
    • 地面と遠景用の Terrain がつながっていると無駄に Bake に時間がかかります
    • 自前でないアセットを使う場合はどうにもならないこともあります

  • 異なるナビメッシュレイヤーが重ならないように注意する
    • あるエージェントが移動可能なレイヤーと移動不可なレイヤーが重なっていると挙動があやしくなるので避けるようにします
    • 地盤(一部エージェントのみ通行可)の上に道路(全エージェントが通行可)を置く場合などにこの状況になりやすいです
    • 上記の場合はほんの少し地盤を下げるとうまく行くこともありますが、地盤と道路のナビメッシュが離れてしまうこともあります

  • さいごの調整手段その 1 : オフメッシュリンク
    • メッシュがつながらない問題はほぼこれで解決できるとおもいます
    • 量が多くなりがちで非常に面倒です

  • さいごの調整手段その 2 : 対象をコピーする
    • たとえば床のナビメッシュがうまくできないとき、床をコピーして、元々の床から Navigation Static のチェックを外し、コピーの床の座標やサイズを調整し、Bake し、コピーを非アクティブ(or 削除)にします
    • 当然面倒です

  • 経路探索のコストに気をつける
    • 経路探索は軽い処理ではないので、使いすぎには注意が必要です
    • 毎フレーム同じ目的地を SetDestination したことがあったのですが、フレーム内に計算が終わらなかったため(?)か、たまに動かないということがありました
      • 筋が悪いと自覚しつつも、ゲームジャムで急ぎだった上にジャム終盤(いろいろ追加して重くなる?)まで動いてたので…

  • 地上でしか使えない
    • これは注意点というよりメモですが、空中や水中を移動するエージェントには不向きです
    • 空中を水平移動するだけなら不可視のメッシュ沿いに移動で問題ないですが、上下左右自在に移動するケースでは使えません

参考


おわりに

注意点などいろいろと書きましたが、Bake さえうまくできてしまえばスクリプトは少なくて済み、他の探索方法のように経路にマーカーオブジェクトを配置する必要もないため非常に便利です。


コメント