【Unity】ナビゲーションシステムを使用して目的地まで移動しよう!
今回はナビゲーションシステムの使い方をご紹介します。
ナビゲーションシステムを使いこなすことができれば、自分が操作していないキャラクターの自動的な移動を実現できることができます。
ゲーム開発には必須の機能ですので、ぜひご参考ください。
本記事は以下の内容をご紹介します。
- ナビゲーションシステムとは
- NavMeshの構築(捜索範囲の構築)
- NavMeshAgentの作成(動かすオブジェクトの作成)
- NavMeshObstacleの設置(障害物の設置)
- OffMeshLinkの作成(ワープポイントの作成)
Contents
ナビゲーションシステムとは
まずはじめにナビゲーションシステムについて簡単にご説明いたします。
ナビゲーションシステムとは、「ナビゲーションメッシュを使用してゲーム世界の中を知的に動くキャラクターを作成する(公式マニュアルより)」システムです。
この機能を使用することで、エージェント(動かしたいキャラクター)を目的地まで簡単に移動させることができます。
↓イメージ図
さらに、 障害物の設置やワープなども実現させることができるとても便利なシステムです。
↓障害物を避けることも可能
では実際に、ナビゲーションシステムを使用する方法を解説していきます。
ナビゲーションシステムの要素
まずはじめにナビゲーションシステムの全体像をイメージしてもらうために、構成要素をご説明します。
ナビゲーションシステムは以下のように構成されています。
- NavMesh(捜索範囲)
- NavMeshAgent(エージェント)
- OffMeshLink(点から点への移動)
- NavMeshObstacle(障害物)
NavMeshの構築をします。
ステージ作成
NavMeshを構築するステージは任意です。ProBuilderなどで階段やスロープを作成すると、よりNavMeshを理解できますのでおすすめです。
↓ProBuilderで作成した今回のデモで使用するステージ
ProBuilderの使用方法は以下の記事をご参考ください。
参考記事)ProBuilderの使用方法
ナビゲーションウィンドウ表示
次にナビゲーションウィンドウを表示します。
以下赤枠Windowメニュー→AI→Navigationを選択してください。
すると以下のようなウィンドウが表示されます。
↓ナビゲーションウィンドウ
ステージにNavMeshを構築していきます。
ステージの地形を元にNavMeshを作成することをNavMesh Bakingと呼びます。
ステージを静的オブジェクトに設定
Bakeすることで静的なゲームオブジェクトとして作成された全てのオブジェクトを処理して、歩行可能な場所をざっくり生成します。
まずはじめにNavMeshを構築するオブジェクト(ステージ)を静的オブジェクトにします。
ヒエラルキービューでステージを選択して、以下赤枠Staticのチェックボックスにチェックを入れてください。
↓Staticにチェックを入れる
これでステージが静的オブジェクトになりました。
NavMesh詳細設定
NavMeshの詳細を設定します。
まずはじめにヒエラルキービューでステージとなるオブジェクトを選択してください。この作業を忘れるとNavMeshを構築できませんのでご注意ください。
次にナビゲーションウィンドウの以下赤枠①Objectを選択して、赤枠②NavigationStaticにチェックを入れてください。
次にNavMeshの範囲を設定します。
ナビゲーションウィンドウの以下赤枠Bakeを選択してください。
各項目について詳しく説明いたします。(GeneratedOffMeshLinksの項目は後ほど説明いたします)
項目 | 意味 |
AgentRadius |
エージェントが壁などに近づける距離
|
AgentHeight |
エージェントの手の届く高さ
|
MaxSlope |
エージェントが登れる坂道の限界角度
|
StepHeight |
エージェントが登れるステップの高さ
|
各項目をご自身のステージにあった値で設定してください。
↓筆者が使用するステージでの設定値
- AgentRadius:0.2
- AgentHeight:0.8
- MaxSlope:56.8
- StepHeight:0.5
設定したら、下部にあるBakeを選択してNavMeshを構築しましょう。
↓以下のように構築されます
後ほどエージェントを動かしたときに違和感があれば、適切な値に設定し直しましょう。
これでNavMeshの構築は完了です。
エージェントの作成をします。
エージェントとなるオブジェクトの作成
まずはじめにエージェントとなるオブジェクトを作成します。
基本的にエージェントとなるオブジェクトは任意ですが、ここではわかりやすくするためにシリンダーを用います。
ヒエラルキービューの以下赤枠Create→3DObject→Cylinderを選択してください。
シリンダーのサイズは任意ですが、ナビゲーションウィンドウのAgent設定で設定されている値に合わせると違和感なく動きます。
↓Agentのサイズ(ステージの関係上、ここでは初期値よりも小さく設定してあります)
ここではシリンダーの名前を「Agent」とします。
目的地となるオブジェクトの作成
次に目的地となるオブジェクトを作成します。
ナビゲーションシステムでは、目的地を座標で設定するので目的地となるオブジェクトの座標を参照させるのが便利です。
ヒエラルキービューの以下赤枠Create→3DObject→Sphereを選択してください。
ここでは作成したSphereの名前を「Goal」とします。
NavMeshAgentコンポーネントをアタッチします。
AddComponent→Navigation→NavMeshAgentを選択してください。
作成したAgentとGoalの位置関係は任意ですが、以下のように配置すると動きがわかりやすくなります。
↓オブジェクト位置関係
エージェントを動かすためのスクリプト作成
エージェントを動かすためのスクリプトを作成します。
プロジェクトビューのCreate→C# Scriptを選択してください。
作成したスクリプトの名前を「Move」とします。
作成したスクリプトを以下のように編集てください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class Move : MonoBehaviour { public Transform goal; //目的地となるオブジェクトのトランスフォーム格納用 private NavMeshAgent agent; //エージェントとなるオブジェクトのNavMeshAgent格納用 // Use this for initialization void Start () { //エージェントのNaveMeshAgentを取得する agent = GetComponent<NavMeshAgent>(); //目的地となる座標を設定する agent.destination = goal.position; } } |
プログラムの解説をします。
目的地となるオブジェクトのトランスフォームを格納するためのパブリックな変数「goal」を準備します。
この変数goalに目的地オブジェクトとして作成したGoalオブジェクトを設定します。
次にスクリプトを設置したナビメッシュエージェントのコンポーネントを格納するプライベートな変数「agent」を準備します。
Start関数でエージェントのナビメッシュエージェントのコンポーネントを取得して、目的地座標を示す「destination」の値をgoal値に書き換えます。
以上がプログラムの解説です。
それではスクリプトをエージェントとなるAgentオブジェクトに設置、Goalオブジェクトを変数goalに設定してください。
↓スクリプトをドラッグ&ドロップで設置
それでは、実行して動きを確認してみましょう。
スロープを登りながら自動的に目的地まで移動しました。
NavMeshObstacleを設置します。
障害物となるオブジェクトの作成
まずはじめに障害物となるオブジェクトをNavMesh上に設置します。
以下のようにNavMeshを遮るようにCubeを設置してください。
CubeにはRigidbodyコンポーネントを追加してください。
NavMeshObstacleコンポーネントの設置
作成したCubeオブジェクトにNavMeshObstacleを設置します。
ヒエラルキービューでCubeを選択して、インスペクタービュー最下部のAddComponent→Navigation→NavMeshObstacleを選択してください。
↓NavMeshObstacleを選択
次にNavMeshObstacleの設定をします。
Sizeの値を調節してNavMeshを遮ります。また、障害物周りの経路が正しくエージェントに認識されるようにCarveにチェックを入れてください。これで障害物で道を塞ぐことができました。
↓NavMeshに反映された状態
それでは、実行して確認してみましょう。
先ほどは最短距離であるスロープの方へ向かいましたが、障害物があることを認識して階段側から目的地に向かいました。
OffMeshLinkの作成(ワープポイントの作成)
OffMeshLinkを作成します。
OffMeshLinkはNavMeshが繋がっていない部分をつなぐ役割を果たします。
スタート地点・ゴール地点オブジェクトの作成
まずはじめにスタート地点となるオブジェクトと、ゴール地点となるオブジェクトを作成します。
どんなオブジェクトを使用しても問題ありませんが、ここではシリンダーを用います。
シリンダーを二つ作成してそれぞれの名前を「Start」、「End」とします。
サイズ等はあまり関係ないので詳しい説明は省略します。
StartとEndの位置を調節します。
ここでは以下のようにStartとEndを設置します。
OffMeshLinkの設置
StartオブジェクトにOffMeshLinkを設置します。
ヒエラルキービューでStartを選択して、インスペクター最下部のAddComponent→Navigation→OffMeshLinkを選択してください。
次にStartとEndをOffMeshLinkにセットします。
↓StartとEndをセット
以上でOffMeshLinkの設定は終了です。
実際に実行して動きを確認してみましょう。
StartからEndに移動していることが確認できました。
まとめ
いかがでしたでしょうか。
今回はナビゲーションシステムの使用方法について解説しました。
今回ご紹介した内容はあくまでも最低限実行するレベルのものです。この動きにキャラクターのアニメーションをつけたり、プレイヤーを追走するようにしたり、ナビゲーションを使用することで様々な場面を実装することができます。
自分なりに動きをアレンジして独自のゲームを開発してみてください。
この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!