概要
ゲームに登場する敵やNPC(ノンプレイヤーキャラクター)が、ただプレイヤーに向かって一直線に突進してくるだけでは、ゲームは単調で面白みに欠けてしまいます。壁や障害物を賢く避け、目的地まで最適なルートを見つけて移動する能力は、説得力のあるAIキャラクターを作る上で不可欠です。この 経路探索(Pathfinding) をUnityで実現するための標準的な機能が、NavMesh(ナビゲーションメッシュ) システムです。
NavMeshシステムは、主に以下 の3つの要素で構成されます。
- NavMesh: AIキャラクターが移動可能なエリアを示す多角形のメッシュ。シーンのジオメトリから自動的に生成(ベイク)されます。
- NavMesh Agent: NavMesh上を移動する能力を持つコンポーネント。AIキャラクターのゲームオブジェクトに追加します。
- NavMesh Obstacle: 動的な障害物(開閉するドアなど)を示すコンポーネント。NavMesh Agentは、これらの障害物を避けてルートを再計算します。
この記事では、静的な地形に対してNavMeshをベイクし、NavMesh Agentを使ってAIキャラクターを目的地まで移動させる基本的な方法を解説します。
Step 1: NavigationウィンドウとNavMeshのベイク
まず、AIに歩かせたいエリアを定義するNavMeshを生成します。
-
Navigationウィンドウを開く: メニューから
Window > AI > Navigationを選択して、Navigationウィンドウを開きます。このウィンドウはObjectとBakeの2つの主要なタブを持っています。 -
静的オブジェクトの設定: NavMeshは、動かない静的なオブジェクトに基づいて生成されます。地面、壁、建物、動かない障害物など、NavMesh生成の対象となるすべてのオブジェクトを選択し、Inspectorの右上にある
StaticドロップダウンからNavigation Staticにチェックを入れます。 -
Agentの設定を調整 (
Bakeタ ブ):Bakeタブでは、NavMeshを生成する際の詳細な設定を行えます。特に重要なのがAgent RadiusとAgent Heightです。Agent Radius: NavMesh Agentの半径。エージェントが通れる通路の幅を決定します。この半径より狭い隙間は、移動不可エリアとして扱われます。Agent Height: NavMesh Agentの高さ。エージェントが通れる高さを決定します。この高さより低い天井の下は、移動不可エリアとなります。Max Slope: エージェントが登れる最大の坂の角度。Step Height: エージェントが乗り越えられる段差の高さ。
これらの値を、AIキャラクターの実際のサイズに合わせて調整します。
-
NavMeshのベイク: 設定が完了したら、
Bakeボタンをクリックします。すると、シーンビュー上に青いポリゴンで覆われたNavMeshが生成されます。これが、AIキャラクターが移動できる範囲です。
Step 2: NavMesh Agentの設定
次に、AIキャラクターにNavMesh上を移動する能力を与えます。
-
NavMesh Agentコンポーネントの追加: AIキャラクターのゲームオブジェクトを選択し、
Add ComponentからNavigation > NavMesh Agentを追加します。 -
Agentのプロパティ調整: InspectorでNavMesh Agentの挙動を調整します。
Speed: エージェントの最大移動速度。Angular Speed: 回転速度。Acceleration: 加速度。Stopping Distance: 目的地にどれだけ近づいたら停止するか。0にすると、目的地に完全に到達しようとして細かく振動することがあるため、少し大きめの値(例:0.5)に設定するのが一般的です。Radius/Height: このエージェントのサイズ。Bake設定のAgent Radius/Heightと一致している必要はありませんが、他のエージェントとの衝突回避などに影響します。
Step 3: スクリプトからAgentを制御する
NavMesh Agentを目的地に移動させるのは非常に簡単です。スクリプトからSetDestination()メソッドを呼び出すだけです。
以下のスクリプトは、プレイヤー(Playerタグが付いているオブジェクト)を追跡する簡単な敵AIの例です。
using UnityEngine;
using UnityEngine.AI; // NavMesh関連のクラスを使うために必要
[RequireComponent(typeof(NavMeshAgent))]
public class EnemyAIController : MonoBehaviour
{
private NavMeshAgent agent;
private Transform playerTarget;
void Start()
{
// NavMeshAgentコンポーネントを取得
agent = GetComponent<NavMeshAgent>();
// プレイヤーオブジェクトを探してターゲットに設定
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
{
playerTarget = player.transform;
}
}
void Update()
{
// ターゲット(プレイヤー)が存在すれば、その位置を目的地に設定し続ける
if (playerTarget != null)
{
agent.SetDestination(playerTarget.position);
}
// Animatorに速度を渡して歩行アニメーションを再生させる(オプション)
// Animator animator = GetComponent<Animator>();
// if (animator != null)
// {
// animator.SetFloat("Speed", agent.velocity.magnitude);
// }
}
}
このスクリプトをNavMesh Agentを持つ敵キャラクターにアタッチするだけで、キャラクターはシーン内の障害物を避けながら、自動的にプレイヤーを追いかけ始めます。
まとめ
UnityのNavMeshシステムを使えば、複雑な経路探索アルゴリズムを自分で実装することなく、簡単に賢いAIナビゲーションを実現できます。
- 移動させたい静的なオブジェクトを
Navigation Staticに設定する。 NavigationウィンドウのBakeタブで、キャラクターのサイズに合わせて設定を調整し、NavMeshをベイクする。- AIキャラクターに
NavMesh Agentコンポーネントを追加し、速度や加速度などを設定する。 - スクリプトから
using UnityEngine.AI;を宣言し、agent.SetDestination(targetPosition);を呼び出してキャラクターを移動させる。
NavMeshは、敵AIだけでなく、味方NPCの追従、街の住人の巡回など、キャラクターの移動に関するあらゆる場面で活用できる非常に強力なシステムです。