Unity のナビゲーションシステム

始めに

ある地点からある地点に地形や障害物を考慮しつつ自動で進むロボットを使ったゲームを考えています。

Unity には経路検索を行ってくれるライブラリがあるのは知っていましたが、 これまで使った事が無かったので調べました。

参考

Navigation System in Unity

移動可能エリアを作る

  1. パッケージマネージャから「AI Navigation」を入れる。

  2. メニュー → ゲームオブジェクト → AI → NaviMesh Surface

  3. 配置されたオブジェクト「NaviMesh Surface」の位置を0,0,0にリセット

  4. NaviMesh Surface の子に、地面にしたいオブジェクトを入れる。

  5. NaviMesh Surface を選択してインスペクタを開き、Object Collection → Collect Objects を Current Object Hierarchy に変更する。

    NaviMesh Surface のデフォルトである All GameObjects だとキャラクタとかも含めて地面扱いになる。対象を絞るため NaviMesh Surface の子オブジェクトだけにした。

  6. インスペクタ下部の Bake ボタンを押す。

  7. なんかそれっぽいエリアが作られる。

移動可能エリア-ヒエラルキー 移動可能エリア-画面

移動オブジェクトとゴール

  1. 移動するオブジェクトを作る。
  2. そのオブジェクトに NavMesh Agent コンポーネントを追加する。
  3. ゴールとなるオブジェクトを作る。

移動オブジェクト-ヒエラルキー 移動オブジェクト-画面

動作を作る

  1. 移動するオブジェクトにスクリプト AgentObjScript を追加

  2. 以下のコードに修正

    using UnityEngine;
    using UnityEngine.AI;
    
    public class AgentObjScript : MonoBehaviour
    {
        public NavMeshAgent Agent;
        public Transform Goal;
    
        public void Start()
        {
            Agent.destination = Goal.position;
        }
    }
    
  3. 移動するオブジェクトを選択して、インスペクタでオブジェクトを割り当て。Agent に自身。Goal にゴールオブジェクト

  4. 実行する。移動する事を確認する。

最後に

比較的実装が簡単なのに高度な事が出来ました。 他には動的に変わる障害物や、移動が遅くなるエリア設定、飛び越えなども出来るそうです。

その他調べたところとして DOTS との兼ね合いです。 鍵となるのが NaviMeshQuery ですが、 実験的実装となっていたので使わない事にしました。 見えないオブジェクトを作って位置や向きを同期とかすれば自分の用途としては十分かなと思います。

top