UnityUnityメモ

Unity初心者でもできる!NavMeshAgentで簡単なAI追尾機能を作ろう

Unity

はじめに

この記事では、NavMeshAgentというUnityの便利な機能を使って、AIキャラクターがプレイヤーを追尾するシステムを簡単に作る方法を解説します。NavMeshAgentを使うと、キャラクターが障害物を避けながらスムーズに移動できるので、複雑なアルゴリズムを考えなくても直感的に実装できます。

Unity初心者でもわかるように、地形の設定からスクリプト作成まで、ステップバイステップで進めていきます。一緒にAI追尾機能を完成させましょう!

Unityを触ったことがないという方はコチラの記事から見てみてください!



1. NavMeshAgentとは?

NavMeshAgentは、Unityに用意された便利なコンポーネントで、キャラクターが自動的に目的地まで移動できる機能を提供します。この機能を使うことで、プレイヤーや敵キャラクターが複雑な地形や障害物を避けながらスムーズに移動することが可能になります。

例えば、敵キャラクターがプレイヤーを追いかけてくるシーンを作る際、普通の移動処理では「障害物を避ける」動きをスクリプトで細かく設定する必要があります。しかし、NavMeshAgentを使えば、これらの処理を自動化できるため、手間を大幅に減らすことができます。

主な特徴

  • 経路探索機能
    キャラクターが障害物を回避しながら目的地まで最適なルートを計算します。
  • リアルタイム追尾
    プレイヤーなどの動くターゲットをリアルタイムで追尾することができます。
  • 簡単な設定
    NavMesh(移動範囲の定義)を設定し、NavMeshAgentをキャラクターに追加するだけで基本的な機能が利用できます。

使う場面

  • 敵がプレイヤーを追いかけるAIを作成する。
  • NPCが指定した目的地まで歩いていくシーンを作成する。
  • ゲーム中の移動可能エリアを制限しつつ、キャラクターを動かしたい場合。

NavMeshAgentは、UnityのAI Navigation機能をベースに動作します。この機能を活用すれば、ゲームの開発効率が大幅に向上するだけでなく、プレイヤーにとってもリアルなゲーム体験を提供することができます。

次のセクションでは、NavMeshAgentを使うための環境をセットアップする方法を詳しく解説していきます!



2. 環境をセットアップする

この記事では、AIキャラクターがプレイヤーを追尾する仕組みを作るために必要な環境のセットアップを行います。ここではUnityのバージョン確認から、地形と障害物の作成までを解説します。


2.1 必要なUnityバージョンとAI Navigationパッケージのインポート

まずは、NavMeshを利用するために必要なUnityバージョンを確認し、必要なパッケージをインポートします。

  1. Unityバージョンを確認する
    Unity 2022.2以降のバージョンでは「AI Navigation」という機能がデフォルトで利用可能です。
    • Unityエディターの上部メニューから「Help」→「About Unity」をクリックして、現在のバージョンを確認してください。
  2. AI Navigationパッケージをインポートする
    以下の手順で必要なパッケージをインポートします。
    • 上部メニューから「Window」→「Package Manager」を選択。
    • パッケージリスト上部の「Packages」プルダウンメニューを「Unity Registry」に切り替えます。
    • 検索バーに「AI Navigation」と入力し、表示されたパッケージを選択。
    • 「Install」ボタンをクリックしてインポートを完了させます。

2.2 地形を作成する

次に、AIキャラクターが移動するための地形を作成します。

  1. 地面を作る
    • ヒエラルキーウィンドウで右クリック→「3D Object」→「Plane」を選択します。
    • 作成されたPlaneが地面になります。必要に応じてインスペクター画面の「Transform」からScaleを調整してください。(例:Scaleを「10, 1, 10」にすると広い地面になります)
  2. 障害物を追加する
    • 地面に障害物を配置することで、よりリアルな移動ルートをシミュレーションできます。
    • ヒエラルキーウィンドウで右クリック→「3D Object」→「Cube」を選択して地形に追加します。
    • Cubeのサイズはインスペクター画面で自由に調整可能です。(例:Scaleを「0.5, 1, 1」にして細長い壁を作成)
    • 必要に応じて、Cubeにマテリアルを追加して見た目を分かりやすくしましょう。



3. NavMeshを設定する

NavMesh(ナビメッシュ)は、キャラクターが移動できる範囲を定義するために使用されます。このセクションでは、NavMeshSurfaceを追加して、移動可能範囲を設定する方法を解説します。


3-1. NavMeshSurfaceを追加する

  1. 地形オブジェクトを選択
    • ヒエラルキー(Hierarchy)ウィンドウで、先ほど作成した「Plane」をクリックします。
    • これがキャラクターが移動する地形になります。
  2. コンポーネントを追加
    • インスペクター(Inspector)ウィンドウで、「Add Component」ボタンをクリックします。
    • 「NavMeshSurface」と検索して追加してください。

3-2. NavMeshをベイク(生成)する

  1. 設定の確認
    • NavMeshSurfaceコンポーネントが追加された状態で、インスペクターを確認します。
    • 「Agent Type」や「Include Layers」などの設定項目がありますが、初心者の場合はデフォルト設定でOKです。
  2. ベイクを実行
    • 「Bake」ボタンを押すと、地形上にNavMeshが生成されます。
    • ベイクが成功すると、地形の上に青いハイライトが表示されます。この青い部分がキャラクターが移動可能な範囲です。

3-3. NavMeshの確認

  1. 移動範囲をチェック
    • 青い範囲が途切れたり、必要な場所をカバーしていない場合は、以下を確認してください。
      • 地形がNavMeshSurfaceとして正しく設定されているか。
      • 障害物(Cubeなど)がNavMeshをブロックしていないか。
  2. 調整が必要な場合
    • NavMeshSurfaceの「Bake」設定で「Agent Radius」や「Agent Height」を調整してみましょう。
    • これにより、移動可能範囲や障害物の避け方が変わります。

ヒント: 障害物の確認方法

障害物が正しくNavMeshに反映されているか確認するには、障害物オブジェクトに「NavMeshObstacle」コンポーネントを追加する方法もあります。この設定により、動的な障害物がある場合でも、リアルタイムでキャラクターが避けて移動できます。


これでNavMeshの設定は完了です!次のステップでは、プレイヤーと敵キャラクターを作成し、実際に動作させてみましょう。



4. プレイヤーキャラクターの作成

この記事では、NavMeshAgentを使ったAI追尾機能のために、まずプレイヤーキャラクターを作成します。プレイヤーキャラクターはゲーム内で移動可能なオブジェクトとなり、敵キャラクターが追いかけるターゲットの役割を果たします。以下の手順で進めていきましょう!


1. プレイヤーオブジェクトの作成

  1. ヒエラルキー(Hierarchy)ウィンドウを右クリックします。
  2. 「3D Object」→「Cube」を選択して、ゲームシーンにキューブを追加します。
  3. 作成したCubeに名前を付けます。わかりやすく「Player」としておくとよいでしょう。

2. Rigidbodyの追加

プレイヤーオブジェクトに物理演算を適用するため、Rigidbodyを追加します。

  1. 「Player」を選択した状態で、インスペクター(Inspector)ウィンドウを確認します。
  2. 「Add Component」ボタンをクリックし、「Rigidbody」と入力して検索します。
  3. 検索結果から「Rigidbody」を選択して追加します。
  4. Rigidbodyを追加することで、物理的な衝突や重力の影響を受けるようになります。

3. 移動用スクリプトの作成

プレイヤーをキーボードで操作できるように、移動用のスクリプトを作成します。

  1. プロジェクトウィンドウで右クリックし、「Create」→「C# Script」を選択します。
  2. スクリプトの名前を「PlayerMove」とします。
  3. 作成したスクリプトを「Player」オブジェクトにドラッグ&ドロップしてアタッチします。

4. スクリプトを編集

「PlayerMove」スクリプトをダブルクリックして開き、以下のコードを入力します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove : MonoBehaviour
{
    void Update()
    {
        // 矢印キーで移動
        if (Input.GetKey(KeyCode.UpArrow))
        {
            transform.Translate(0f, 0f, 0.1f);
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            transform.Translate(0f, 0f, -0.1f);
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            transform.Translate(-0.1f, 0f, 0f);
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            transform.Translate(0.1f, 0f, 0f);
        }
    }
}

このコードでは、矢印キー(上下左右)を使用してCubeが移動できるように設定しています。


5. テストして動作確認

スクリプトを保存してUnityに戻り、以下を確認してください。

  1. シーンビューで「Player」オブジェクトが選択されていることを確認します。
  2. 再生ボタン(Play)をクリックしてゲームを開始します。
  3. キーボードの矢印キーを押し、「Player」が正しく移動するか確認します。

これでプレイヤーキャラクターの作成は完了です!次のステップでは、敵キャラクターを作成し、プレイヤーを追尾させる仕組みを実装します。



5. 敵キャラクターの作成

このセクションでは、プレイヤーを追いかけてくる敵キャラクターを作成します。UnityのNavMeshAgentを利用して、障害物を避けながらプレイヤーを追尾する動きを実現しましょう!


敵キャラクターの作成手順

  1. 敵キャラクターのオブジェクトを作成する
    • ヒエラルキーウィンドウで、右クリック →「3D Object」→「Sphere」を選択します。
    • 作成したスフィアに「Enemy」という名前を付けます。
    • スフィアの位置を調整して、地面(Plane)の上に配置しましょう。
  2. NavMeshAgentコンポーネントを追加する
    • 作成した「Enemy」を選択します。
    • インスペクターウィンドウの「Add Component」ボタンをクリック。
    • 検索バーに「NavMeshAgent」と入力し、追加します。
    • NavMeshAgentには、自動的にキャラクターを目的地まで移動させる機能があります。

敵キャラ用のスクリプトを作成する

次に、敵キャラクターがプレイヤーを追いかける動きをスクリプトで実装します。

  1. スクリプトファイルを作成
    • プロジェクトウィンドウで右クリック →「Create」→「C# Script」を選びます。
    • 新しいスクリプトの名前を「EnemyMove」に変更します。
  2. スクリプトを編集
    • 作成したスクリプトをダブルクリックして開き、以下のコードを入力してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyMove : MonoBehaviour
{
    NavMeshAgent agent; // NavMeshAgentコンポーネントを格納する変数
    public GameObject target; // 追尾対象のオブジェクト

    void Start()
    {
        // NavMeshAgentコンポーネントを取得
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        // 追尾対象(target)の位置を目的地に設定
        agent.destination = target.transform.position;
    }
}

スクリプトをアタッチする

  1. スクリプトを敵キャラクターに設定
    • 作成したスクリプト「EnemyMove」を「Enemy」オブジェクトにドラッグ&ドロップしてアタッチします。
  2. プレイヤーを追尾対象として設定
    • ヒエラルキーウィンドウで「Enemy」を選択します。
    • インスペクターウィンドウ内の「EnemyMove」スクリプトのTargetフィールドに、プレイヤーオブジェクト(Cube)をドラッグ&ドロップします。



6. テストプレイ

ここまでの手順を終えたら、いよいよ作成したAI追尾機能が正しく動作するかを確認します。以下のステップでテストプレイを行いましょう。


1. ゲームを再生する

Unityエディターの上部にある「再生ボタン(▶)」をクリックします。
すると、ゲームがスタートし、シーン内のオブジェクトが動作を始めます。


2. プレイヤーを操作する

キーボードの矢印キー(↑、↓、←、→)を使って、プレイヤーオブジェクトを操作してみましょう。
プレイヤーがスムーズに移動できるかを確認してください。


3. 敵キャラクターの追尾を確認する

敵キャラクター(Sphere)がプレイヤー(Cube)の位置を追尾しているか確認してください。以下のポイントをチェックしましょう:

  • 敵キャラクターが障害物を回避しながら移動している
  • プレイヤーに近づくにつれて敵キャラクターの動きが適切に調整されている

4. 動作に問題がある場合

テストプレイ中に問題が発生した場合、以下を確認してください。

  • NavMeshの設定
    NavMeshが正しくベイクされていない可能性があります。地形(Plane)に設定した「NavMeshSurface」を選び、「Bake」を再度実行してください。
  • ターゲットの設定
    敵キャラクター(Sphere)のインスペクターにある「Target」フィールドに、正しいプレイヤーオブジェクト(Cube)が設定されているか確認してください。
  • スクリプトのエラー
    スクリプトにエラーがないか、コンソールウィンドウをチェックしてください。エラーが表示されている場合、該当箇所を修正してください。

これでテストプレイの工程は完了です!問題なく動作するようになったら、次の段階でさらなる機能追加や演出を考えてみましょう。新しいアイデアを試すのもUnityの楽しさの一つです!



7.AIが特定の範囲に入ったプレイヤーを追尾する仕組み

AIキャラクターに追尾機能を持たせるだけではなく、特定のエリアに入ったときだけ追尾を開始する仕組みを追加してみましょう。この方法を使えば、より現実的な動きを持つ敵キャラクターを作ることができます。


1. トリガーエリアを作成する

まず、プレイヤーが近づいたことを感知するための「トリガーエリア」を作成します。このエリア内にプレイヤーが入った場合のみ、AIキャラクターが追尾を開始するように設定します。

手順

  1. 空のオブジェクトを作成
    ヒエラルキーウィンドウで右クリックし、「Create Empty」を選択します。名前を「ChaseArea」に変更しましょう。
  2. Sphere Colliderを追加
    「ChaseArea」を選択し、インスペクター画面から「Add Component」をクリックして「Sphere Collider」を追加します。以下の設定を行います:
    • Is Trigger: チェックを入れる
    • Position: (-3, 0, 3)
    • Radius: 2

これで、トリガーエリアが完成しました!


2. プレイヤー用スクリプトを変更する

トリガーエリアにプレイヤーが入ったことを検知するために、PlayerMoveスクリプトを編集します。

スクリプトの内容

以下のコードを追記します:

void OnTriggerStay(Collider other)
{
if (other.gameObject.name == "ChaseArea")
{
isArea = true;
}
}

void OnTriggerExit(Collider other)
{
if (other.gameObject.name == "ChaseArea")
{
isArea = false;
}
}

コードの動き

  • プレイヤーが「ChaseArea」に入った場合、isAreatrueになります。
  • プレイヤーがエリア外に出た場合、isAreafalseになります。

3. 敵用スクリプトを変更する

次に、敵キャラクターがプレイヤーのエリア内外を判別し、追尾するかどうかを制御します。

スクリプトの内容

以下のコードを追記します:

void Update()
{
if (target.GetComponent<PlayerMove>().isArea == true)
{
agent.destination = target.transform.position;
}
}

コードの動き

  • プレイヤーがエリア内にいる間だけ、NavMeshAgentがプレイヤーを追尾します。
  • エリア外では追尾を停止します。

4. テストプレイ

すべての設定が完了したら、シーンを再生して動作を確認しましょう。

確認ポイント

  • プレイヤーがトリガーエリアに入ると敵が追尾を開始する。
  • プレイヤーがエリア外に出ると敵が追尾を停止する。

これで特定のエリア内でのみAIが追尾する仕組みが完成しました。この仕組みを使えば、ゲームプレイに深みを与え、より魅力的な敵キャラクターを作ることができます。次回は、この機能をさらに拡張して、エリアごとに異なる敵の行動パターンを追加する方法について解説します!



8.プレイヤーが特定座標に到達したらAIが追いかける仕組み

AIキャラクターがプレイヤーを追いかける機能をさらにカスタマイズ!次は、プレイヤーが特定の座標に到達したときだけ敵キャラクターが追尾を開始する仕組みを作ります。X座標が0を超えると追いかけ、X座標が0以下になると追尾をやめる簡単な方法を紹介します。


特定座標トリガーとは?

特定座標トリガーとは、プレイヤーが指定された座標範囲に入ったときだけ特定の動作(この場合はAIの追尾)を実行する仕組みです。これにより、ゲームに動的な要素を加え、より自然なプレイ体験を提供できます。


手順1:プレイヤーの座標を判定する

まずはプレイヤーが特定の座標にいるかどうかを判定するスクリプトを追加します。

「PlayerMove」スクリプトの修正

  1. Unityで「PlayerMove」スクリプトをダブルクリックして開きます。
  2. 以下のコードを追加または修正してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMove : MonoBehaviour
{
    public bool isArea; // 座標判定用のフラグ

    void Start()
    {
        isArea = false; // 初期状態は追尾を停止
    }

    void Update()
    {
        // プレイヤーの移動処理
        if (Input.GetKey(KeyCode.UpArrow))
        {
            transform.Translate(0f, 0f, 0.01f);
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            transform.Translate(0f, 0f, -0.01f);
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            transform.Translate(-0.01f, 0f, 0f);
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            transform.Translate(0.01f, 0f, 0f);
        }

        // 特定の座標判定 (X > 0)
        if (transform.position.x > 0)
        {
            isArea = true; // フラグを有効化
        }
        else
        {
            isArea = false; // フラグを無効化
        }
    }
}

このコードでは、プレイヤーのX座標が0を超えたときにisAreatrueになり、それ以下の場合はfalseに戻ります。


手順2:敵キャラクターの追尾を調整する

次に、敵キャラクターがこのisAreaフラグを参照して動作を変更するようにスクリプトを修正します。

「EnemyMove」スクリプトの修正

  1. Unityで「EnemyMove」スクリプトをダブルクリックして開きます。
  2. 以下のコードを追加または修正してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class EnemyMove : MonoBehaviour
{
    NavMeshAgent agent; // NavMeshAgentの参照
    public GameObject target; // プレイヤーのオブジェクト

    void Start()
    {
        agent = GetComponent<NavMeshAgent>(); // NavMeshAgentを取得
    }

    void Update()
    {
        // プレイヤーが特定の座標にいる場合追尾開始
        if (target.GetComponent<PlayerMove>().isArea == true)
        {
            agent.destination = target.transform.position; // プレイヤーを追尾
        }
        else
        {
            agent.destination = this.transform.position; // その場で待機
        }
    }
}

手順3:テストプレイ

  1. Unityエディターでシーンを実行します。
  2. プレイヤーが移動し、X座標が0を超えた瞬間に敵キャラクターが追尾を開始することを確認します。
  3. プレイヤーがX座標0以下に戻った際、敵キャラクターがその場で停止することを確認します。

これで、特定の座標に到達したときだけAIが追いかける仕組みが完成です!この仕組みを使えば、ゲームに緊張感や戦略性を持たせることができます。ぜひ試してみてください!



よくある質問(FAQ)

Q
NavMeshが正しくベイクされない場合はどうすればいいですか?
A

NavMeshのベイクが失敗する場合、以下のポイントを確認してください:

  • オブジェクトのLayer設定
    NavMeshSurfaceを追加したオブジェクトや障害物が適切なLayerに設定されているか確認しましょう。「Default」や指定したLayerが正しいかチェックしてください。
  • 地形がStaticになっているか
    ベイク対象の地形や障害物に「Static」のチェックが付いているか確認してください。これが設定されていないとNavMeshが生成されません。
  • NavMeshSurfaceの設定
    NavMeshSurfaceコンポーネントの「Include Layers」に対象のLayerが含まれているか確認してください。
Q
敵キャラクターがプレイヤーを追いかけてこないのはなぜですか?
A

以下の点を確認してみてください:

  • NavMeshAgentの設定
    敵キャラクターに追加した「NavMeshAgent」コンポーネントの「Agent Radius」や「Obstacle Avoidance」が適切に設定されているか確認してください。
  • スクリプトのtarget設定
    スクリプトで設定した「target」にプレイヤーオブジェクトが正しくアサインされているか確認してください。インスペクターで「Player」がドラッグ&ドロップされているかチェックしましょう。
  • NavMesh上にキャラクターがいるか
    敵キャラクターがNavMeshの範囲外にいると追いかけることができません。NavMeshの中に配置されていることを確認してください。
Q
プレイヤーキャラクターが移動しない場合の原因は?
A

プレイヤーが動かない場合、以下をチェックしてください:

  • スクリプトのアタッチ漏れ
    作成したスクリプト「PlayerMove」がプレイヤーオブジェクトにアタッチされているか確認してください。
  • Rigidbodyの設定
    プレイヤーオブジェクトに「Rigidbody」コンポーネントが追加されているか確認してください。また、Is Kinematicのチェックをオフにする必要があります。
  • コードの誤り
    PlayerMoveスクリプトに誤りがないか確認してください。特にInput.GetKeyの部分でキーが正しく設定されているかをチェックしましょう。

おすすめのアセット

「Car Chase – Complete Game Template」は、Unityでカーチェイスゲームを素早く作成できるテンプレートです。カスタマイズ可能な3D車両や武器システム、無限ランナーの要素が含まれており、リアルタイムのアクションやレースゲームに最適です。ビルトイン、URP、HDRPすべてのレンダーパイプラインに対応しており、すぐにプレイ可能なプロジェクトとして活用できます。初心者から上級者まで使いやすく、スピード感あふれるゲームを短期間で制作できます。