【Unity】ナビゲーションシステムを使用して目的地まで移動しよう!


今回はナビゲーションシステムの使い方をご紹介します。

ナビゲーションシステムを使いこなすことができれば、自分が操作していないキャラクターの自動的な移動を実現できることができます。

ゲーム開発には必須の機能ですので、ぜひご参考ください。

ナビゲーションドキュメント

本記事は以下の内容をご紹介します。

  • ナビゲーションシステムとは
  • NavMeshの構築(捜索範囲の構築)
  • NavMeshAgentの作成(動かすオブジェクトの作成)
  • NavMeshObstacleの設置(障害物の設置)
  • OffMeshLinkの作成(ワープポイントの作成)

ナビゲーションシステムとは

まずはじめにナビゲーションシステムについて簡単にご説明いたします。

ナビゲーションシステムとは、「ナビゲーションメッシュを使用してゲーム世界の中を知的に動くキャラクターを作成する(公式マニュアルより)」システムです。

この機能を使用することで、エージェント(動かしたいキャラクター)を目的地まで簡単に移動させることができます。

↓イメージ図

ナビゲーションシステム概要

さらに、 障害物の設置やワープなども実現させることができるとても便利なシステムです。

↓障害物を避けることも可能

障害物を避けて移動イメージ

では実際に、ナビゲーションシステムを使用する方法を解説していきます。

ナビゲーションシステムの要素

まずはじめにナビゲーションシステムの全体像をイメージしてもらうために、構成要素をご説明します。

ナビゲーションシステムは以下のように構成されています。

  • NavMesh(捜索範囲)
  • NavMeshAgent(エージェント)
  • OffMeshLink(点から点への移動)
  • NavMeshObstacle(障害物)

ナビゲーションシステム基本構成

NavMeshの構築

NavMeshの構築をします。

ステージ作成

NavMeshを構築するステージは任意です。ProBuilderなどで階段やスロープを作成すると、よりNavMeshを理解できますのでおすすめです。

↓ProBuilderで作成した今回のデモで使用するステージ

使用するステージ

ProBuilderの使用方法は以下の記事をご参考ください。

参考記事)ProBuilderの使用方法

ナビゲーションウィンドウ表示

次にナビゲーションウィンドウを表示します。

以下赤枠Windowメニュー→AI→Navigationを選択してください。

ナビゲーションウィンドウ表示

すると以下のようなウィンドウが表示されます。

↓ナビゲーションウィンドウ

ナビゲーションウィンドウ

ステージにNavMeshを構築していきます。

ステージの地形を元にNavMeshを作成することをNavMesh Bakingと呼びます。

ステージを静的オブジェクトに設定

Bakeすることで静的なゲームオブジェクトとして作成された全てのオブジェクトを処理して、歩行可能な場所をざっくり生成します。

まずはじめにNavMeshを構築するオブジェクト(ステージ)を静的オブジェクトにします。

ヒエラルキービューでステージを選択して、以下赤枠Staticのチェックボックスにチェックを入れてください。

↓Staticにチェックを入れる

静的オブジェクトに設定

これでステージが静的オブジェクトになりました。

NavMesh詳細設定

NavMeshの詳細を設定します。

まずはじめにヒエラルキービューでステージとなるオブジェクトを選択してください。この作業を忘れるとNavMeshを構築できませんのでご注意ください。

次にナビゲーションウィンドウの以下赤枠①Objectを選択して、赤枠②NavigationStaticにチェックを入れてください。

Staticにチェック

次にNavMeshの範囲を設定します。

ナビゲーションウィンドウの以下赤枠Bakeを選択してください。

Bake選択

各項目について詳しく説明いたします。(GeneratedOffMeshLinksの項目は後ほど説明いたします)

項目 意味
AgentRadius
エージェントが壁などに近づける距離
AgentHeight
エージェントの手の届く高さ
MaxSlope
エージェントが登れる坂道の限界角度
StepHeight
エージェントが登れるステップの高さ

各項目をご自身のステージにあった値で設定してください。

↓筆者が使用するステージでの設定値

設定値の例

  • AgentRadius:0.2
  • AgentHeight:0.8
  • MaxSlope:56.8
  • StepHeight:0.5

設定したら、下部にあるBakeを選択してNavMeshを構築しましょう。

↓以下のように構築されます

ナビメッシュ構築例

後ほどエージェントを動かしたときに違和感があれば、適切な値に設定し直しましょう。

これでNavMeshの構築は完了です。

NavMeshAgentの作成(動かすオブジェクトの作成)

エージェントの作成をします。

エージェントとなるオブジェクトの作成

まずはじめにエージェントとなるオブジェクトを作成します。

基本的にエージェントとなるオブジェクトは任意ですが、ここではわかりやすくするためにシリンダーを用います。

ヒエラルキービューの以下赤枠Create→3DObject→Cylinderを選択してください。

シリンダー作成

シリンダーのサイズは任意ですが、ナビゲーションウィンドウのAgent設定で設定されている値に合わせると違和感なく動きます。

↓Agentのサイズ(ステージの関係上、ここでは初期値よりも小さく設定してあります)

Agentサイズ設定

ここではシリンダーの名前を「Agent」とします。

目的地となるオブジェクトの作成

次に目的地となるオブジェクトを作成します。

ナビゲーションシステムでは、目的地を座標で設定するので目的地となるオブジェクトの座標を参照させるのが便利です。

ヒエラルキービューの以下赤枠Create→3DObject→Sphereを選択してください。

目的地オブジェクト作成

ここでは作成したSphereの名前を「Goal」とします。

NavMeshAgentコンポーネントをアタッチします。

AddComponent→Navigation→NavMeshAgentを選択してください。

NavMeshAgentアタッチ

作成したAgentとGoalの位置関係は任意ですが、以下のように配置すると動きがわかりやすくなります。

↓オブジェクト位置関係

ゴールとエージェントの位置関係

エージェントを動かすためのスクリプト作成

エージェントを動かすためのスクリプトを作成します。

プロジェクトビューのCreate→C# Scriptを選択してください。

作成したスクリプトの名前を「Move」とします。

作成したスクリプトを以下のように編集てください。

プログラムの解説をします。

目的地となるオブジェクトのトランスフォームを格納するためのパブリックな変数「goal」を準備します。

この変数goalに目的地オブジェクトとして作成したGoalオブジェクトを設定します。

次にスクリプトを設置したナビメッシュエージェントのコンポーネントを格納するプライベートな変数「agent」を準備します。

Start関数でエージェントのナビメッシュエージェントのコンポーネントを取得して、目的地座標を示す「destination」の値をgoal値に書き換えます。

以上がプログラムの解説です。

それではスクリプトをエージェントとなるAgentオブジェクトに設置、Goalオブジェクトを変数goalに設定してください。

↓スクリプトをドラッグ&ドロップで設置

Moveスクリプト適用

それでは、実行して動きを確認してみましょう。

ナビゲーションシステム通常実行

スロープを登りながら自動的に目的地まで移動しました。

NavMeshObstacleの設置(障害物の設置)

NavMeshObstacleを設置します。

障害物となるオブジェクトの作成

まずはじめに障害物となるオブジェクトをNavMesh上に設置します。

以下のようにNavMeshを遮るようにCubeを設置してください。

CubeにはRigidbodyコンポーネントを追加してください。

障害物設置

NavMeshObstacleコンポーネントの設置

作成したCubeオブジェクトにNavMeshObstacleを設置します。

ヒエラルキービューでCubeを選択して、インスペクタービュー最下部のAddComponent→Navigation→NavMeshObstacleを選択してください。

↓NavMeshObstacleを選択

NavMeshObstacle設置

次にNavMeshObstacleの設定をします。

NavMeshObstacle設定

Sizeの値を調節してNavMeshを遮ります。また、障害物周りの経路が正しくエージェントに認識されるようにCarveにチェックを入れてください。これで障害物で道を塞ぐことができました。

↓NavMeshに反映された状態

障害物によって道を塞ぐ

それでは、実行して確認してみましょう。

障害物あり実行結果

先ほどは最短距離であるスロープの方へ向かいましたが、障害物があることを認識して階段側から目的地に向かいました。

OffMeshLinkの作成(ワープポイントの作成)

OffMeshLinkを作成します。

OffMeshLinkはNavMeshが繋がっていない部分をつなぐ役割を果たします。

スタート地点・ゴール地点オブジェクトの作成

まずはじめにスタート地点となるオブジェクトと、ゴール地点となるオブジェクトを作成します。

どんなオブジェクトを使用しても問題ありませんが、ここではシリンダーを用います。

シリンダーを二つ作成してそれぞれの名前を「Start」、「End」とします。

スタート地点オブジェクト

サイズ等はあまり関係ないので詳しい説明は省略します。

StartとEndの位置を調節します。

ここでは以下のようにStartとEndを設置します。

スタートエンド設置

OffMeshLinkの設置

StartオブジェクトにOffMeshLinkを設置します。

ヒエラルキービューでStartを選択して、インスペクター最下部のAddComponent→Navigation→OffMeshLinkを選択してください。

OffMeshLink設置

次にStartとEndをOffMeshLinkにセットします。

↓StartとEndをセット

StartEnd設定

以上でOffMeshLinkの設定は終了です。

実際に実行して動きを確認してみましょう。

OffMeshLink実行結果

StartからEndに移動していることが確認できました。

まとめ

いかがでしたでしょうか。

今回はナビゲーションシステムの使用方法について解説しました。

今回ご紹介した内容はあくまでも最低限実行するレベルのものです。この動きにキャラクターのアニメーションをつけたり、プレイヤーを追走するようにしたり、ナビゲーションを使用することで様々な場面を実装することができます。

自分なりに動きをアレンジして独自のゲームを開発してみてください。


Furui