UnityUnityメモ

【Unity2D】敵がプレイヤーを追跡!簡単AIの作り方

Unity

1. はじめに

Unityで2Dゲームを作るとき、「敵キャラをプレイヤーに追跡させたい!」と思うことはありませんか?
シューティングゲームやアクションゲームでは、敵がプレイヤーに向かって移動する動きがあると、ゲームの面白さが一気にアップします。

この記事では、Unity2Dで敵キャラがプレイヤーを追いかける仕組みを簡単に実装する方法を紹介します。
Rigidbody2D を活用して、スムーズにプレイヤーを追跡するAIを作っていきます。

この記事で学べること

  • プレイヤーと敵キャラの配置方法
  • Rigidbody2D を使ったプレイヤーの移動スクリプト
  • 敵がプレイヤーを追跡するスクリプトの作成
  • スムーズな追跡動作の実装方法

それでは、さっそくプレイヤーと敵キャラを配置するところから始めましょう!


今回は、プレイヤーを追跡する敵キャラの作り方を解説しますが、もし 「すぐに遊べる2Dシューティングゲームのテンプレートが欲しい!」 という方は、
2D Plane Shooting Game Sample をチェックしてみてください!
すぐに動くシューティングゲームのサンプルが手に入るので、コードを参考にしながらカスタマイズするのもおすすめです!




2. プレイヤーと敵キャラの配置

それでは、まず プレイヤーと敵キャラをシーンに配置 しましょう。
今回使用するのは、Unityアセットストアの Vertical 2D Shooting Assets Pack です。
このアセットを使えば、シューティングゲームにぴったりなキャラクターやエフェクトを簡単に導入できます。


① プレイヤーと敵のオブジェクトを作成

  1. ヒエラルキー(Hierarchy)ウィンドウを開き、プレイヤーオブジェクトを作成
    • ヒエラルキーで右クリック → 2D ObjectSprite を選択
    • 名前を「Player」 に変更
    • インスペクター(Inspector)ウィンドウで スプライト画像をプレイヤーの見た目に変更
  2. 敵キャラオブジェクトを作成
    • もう一度 2Dオブジェクト(Sprite) を作成
    • 名前を「Enemy」 に変更
    • スプライト画像を 敵の見た目に変更

② Rigidbody2D を追加

プレイヤーと敵キャラのオブジェクトに 物理演算を適用 するために Rigidbody2D を追加します。

  1. プレイヤーの Rigidbody2D 設定
    • ヒエラルキーで「Player」を選択
    • インスペクターで「Add Component」をクリック
    • Rigidbody2D を検索して追加
    • 設定を変更
      • Gravity Scale0(重力を無効化)
      • Freeze Rotation(Z軸)(回転を固定)
  2. 敵キャラの Rigidbody2D 設定
    • ヒエラルキーで「Enemy」を選択
    • インスペクターで「Add Component」から Rigidbody2D を追加
    • 設定を変更
      • Gravity Scale0
      • Freeze Rotation(Z軸)

③ 簡単な動作確認

ここまでの設定が正しく行われているか確認するために、シーンビューで PlayerEnemy の配置を調整し、敵キャラをプレイヤーの近くに配置 しておきましょう。

すべてのオブジェクトが 適切な位置にあることを確認 できたら、次は プレイヤーを移動させるスクリプト を作成していきます!




3. プレイヤーの移動スクリプト

プレイヤーと敵キャラをシーンに配置できたら、次は プレイヤーを移動できるようにするスクリプト を作成しましょう。
プレイヤーが WASD キーや矢印キーで自由に動けるように、 Rigidbody2D を使った移動処理を実装します。


① C#スクリプト「Player.cs」を作成

  1. プロジェクトウィンドウを開く
  2. Assets フォルダ内で右クリック
    CreateC# Script を選択
  3. 新しいスクリプトの名前を 「Player」 に変更
  4. 作成したスクリプトを開き、以下のコードを入力
using UnityEngine;

public class Player : MonoBehaviour
{
    float moveSpeed = 5f; // 移動速度
    [SerializeField] Rigidbody2D rb; // Rigidbody2D の参照

    Vector2 movement; // 移動方向

    void Update()
    {
        // 入力の取得(WASDキーや矢印キー)
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");
    }

    private void FixedUpdate()
    {
        // Rigidbody2D を使って移動
        rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
    }
}

② スクリプトの解説

このスクリプトでは、以下のような処理を行っています。

Update() で移動入力を取得

  • Input.GetAxisRaw("Horizontal") → 左右の移動(A / D or /
  • Input.GetAxisRaw("Vertical") → 上下の移動(W / S or /

FixedUpdate() で Rigidbody2D を使って移動

  • rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime); でスムーズな移動を実現

③ スクリプトをプレイヤーオブジェクトにアタッチ

次に、作成した Player スクリプトを プレイヤーオブジェクトに適用 します。

  1. ヒエラルキーで「Player」オブジェクトを選択
  2. インスペクターウィンドウで「Add Component」をクリック
  3. 「Player」スクリプトを検索して追加
  4. Rigidbody2D をスクリプトの rb フィールドにドラッグ&ドロップ

④ 動作確認

ここまで設定が完了したら、Unityを再生(Play) して、以下のポイントをチェックしましょう。

矢印キー / WASDキーでプレイヤーが動くか?
動きがスムーズに見えるか?
動かない場合は Rigidbody2D の設定を確認!

もしプレイヤーが動かない場合は、Rigidbody2D を正しく設定しているか 確認してください。

次は、プレイヤーを追跡する敵AIを実装 していきます!




4. 敵の追跡スクリプト

プレイヤーが自由に動けるようになったので、次は 敵キャラをプレイヤーに向かって移動させる 仕組みを作ります!
敵が自動的にプレイヤーを追いかけるように、Rigidbody2D を使ってスムーズな動きを実装していきましょう。


① C#スクリプト「Enemy.cs」を作成

  1. プロジェクトウィンドウを開く
  2. Assets フォルダ内で右クリック
    CreateC# Script を選択
  3. 新しいスクリプトの名前を 「Enemy」 に変更
  4. 作成したスクリプトを開き、以下のコードを入力
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class Enemy : MonoBehaviour
{
    [SerializeField] Transform target; // 追跡する対象(プレイヤー)
    Rigidbody2D rb;
    float speed = 5f; // 移動速度
    float rotateSpeed = 200f; // 回転速度

    void Start()
    {
        rb = GetComponent<Rigidbody2D>(); // Rigidbody2D を取得
    }

    void Update()
    {
        if (target == null) return;

        // プレイヤーの方向を取得
        Vector2 direction = (Vector2)target.position - rb.position;
        direction.Normalize();

        // 回転の計算
        float rotateAmount = Vector3.Cross(direction, transform.up).z;
        rb.angularVelocity = -rotateAmount * rotateSpeed;

        // 前進
        rb.velocity = transform.up * speed;
    }
}

② スクリプトの解説

このスクリプトでは、以下のような処理を行っています。

target に設定したプレイヤーの位置を取得

  • Vector2 direction = (Vector2)target.position - rb.position;
    → 敵からプレイヤーまでの方向を計算

プレイヤーの方向に向かって回転

  • float rotateAmount = Vector3.Cross(direction, transform.up).z;
    Vector3.Cross() を使って回転量を計算し、rb.angularVelocity に適用
    → これでスムーズにプレイヤーの方向を向くようになる

前進する動きを加える

  • rb.velocity = transform.up * speed;
    transform.up(現在向いている方向)に speed をかけて移動

③ スクリプトを敵キャラにアタッチ

次に、作成した Enemy スクリプトを 敵キャラオブジェクトに適用 します。

  1. ヒエラルキーで「Enemy」オブジェクトを選択
  2. インスペクターウィンドウで「Add Component」をクリック
  3. 「Enemy」スクリプトを検索して追加
  4. target フィールドに「Player」オブジェクトをドラッグ&ドロップ

これで 敵はプレイヤーをターゲットとして認識 し、動くようになります!




5. 動作確認とデバッグ

ここまでの設定が完了したら、実際にプレイヤーを動かし、敵がしっかり追跡するか を確認してみましょう。
うまく動作しない場合のトラブルシューティングも紹介するので、問題があればチェックしてみてください!


① 基本的な動作確認

  1. Unityを再生(Play) してゲームをスタート
  2. 矢印キーまたは WASDキー でプレイヤーを移動
  3. 敵キャラがプレイヤーを追いかけているか確認

プレイヤーが自由に動けるか?
敵がプレイヤーを見つけて追跡しているか?
敵の動きがスムーズか?(ガタガタしないか)

もし プレイヤーが動かない・敵が追跡しない 場合は、次のトラブルシューティングを試してみてください。


② トラブルシューティング

💡 プレイヤーが動かない場合Player スクリプトがプレイヤーオブジェクトにアタッチされているか 確認
Rigidbody2DGravity Scale0 になっているか
rb フィールドに プレイヤーの Rigidbody2D が設定されているか


💡 敵がプレイヤーを追いかけない場合Enemy スクリプトが敵キャラオブジェクトにアタッチされているか 確認
target フィールドに プレイヤーオブジェクトが設定されているか
Rigidbody2DGravity Scale0 になっているか
Freeze Rotation(Z軸) のチェックを外しているか
✔ 敵がプレイヤーと 十分な距離があるか(近すぎると動きがわかりづらい)


💡 敵の動きがガタガタしている場合FixedUpdate() ではなく Update()velocity を設定していないか?
velocity の設定は FixedUpdate() で行うとスムーズになる
回転の値 (rotateSpeed) が高すぎないか?
rotateSpeed100f200f の間で調整
敵の速度 (speed) が速すぎないか?
speed3f5f くらいに調整


③ スムーズな追跡動作にするための調整

敵の動きをよりスムーズにするためには、以下の調整を試してみましょう。

🔹 敵の移動速度を調整
speed の値を 3f5f の範囲で調整すると、自然な追跡動作になります。

🔹 回転速度 (rotateSpeed) を調整
回転速度が高すぎると、敵がプレイヤーの方向を急に変えてカクつくことがあります。
rotateSpeed = 150f くらいに設定すると、スムーズな旋回になります。

🔹 敵の追跡範囲を制限する(オプション)
もし敵がずっとプレイヤーを追いかけ続けるのではなく、一定範囲内でのみ追跡するようにしたい場合は、以下のようなコードを追加します。

float chaseRange = 10f; // 追跡する範囲

void Update()
{
if (target == null) return;

float distance = Vector2.Distance(target.position, rb.position);
if (distance > chaseRange) return; // プレイヤーが範囲外なら追跡しない

Vector2 direction = (Vector2)target.position - rb.position;
direction.Normalize();

float rotateAmount = Vector3.Cross(direction, transform.up).z;
rb.angularVelocity = -rotateAmount * rotateSpeed;
rb.velocity = transform.up * speed;
}

これを追加すると、敵がプレイヤーから 10ユニット以上離れていると追跡しなくなる ので、より自然なゲームプレイが作れます。


④ まとめ

これで、敵がプレイヤーを追跡する仕組み の動作確認とデバッグができました!

プレイヤーが自由に動けるようになった
敵キャラがスムーズにプレイヤーを追跡するようになった
回転速度や移動速度を調整することで、よりスムーズな動きを実現できた

もしさらなる改善をしたい場合は、敵のパトロールAIを追加 したり、障害物を避ける機能 を実装してみるのもおすすめです!

「敵を追跡させるAIを作る方法がわかったけど、もっと本格的なシューティングゲームを作りたい!」 という方は、
2D Plane Shooting Game Sample を試してみるのもおすすめです!
プレイヤーの移動・攻撃・敵の動きなど、すでにゲームとして動く仕組みが含まれている ので、そこからコードを学びながら改良することもできますよ!




よくある質問(FAQ)

Q
敵がプレイヤーを追跡しません。原因は?
A

targetの設定が正しいか確認してください。敵スクリプトのtargetにプレイヤーオブジェクトをドラッグ&ドロップする必要があります。

Q
敵がすぐに回転してしまい、動きが不自然です。
A

rotateSpeedの値を調整してみてください。小さくすると、スムーズな旋回になります。

Q
プレイヤーの移動が遅すぎる/速すぎる場合は?
A

moveSpeedの値を調整してください。また、Time.fixedDeltaTimeを適切に活用することも重要です。

おすすめのアセット

タイトルとURLをコピーしました