【Unity】(2D)特定範囲内に入っている敵を見つける

2Dゲームを開発中に特定範囲内にいる敵を見つける場合、Physics2D.OverlapCircleAll関数を使用します。この関数は指定した中心点と半径を持つ円内に存在する全てのコライダーを検出し、Collider2Dの配列として返します。適用するレイヤーマスクにより、敵キャラクターのみを対象とすることが可能です。この方法は、プレイヤーの攻撃範囲内に敵がいるか確認するのに特に有用で、エリアベースの攻撃やトリガーイベントの処理に役立ちます。

サンプルコード

using UnityEngine;

public class EnemyDetection : MonoBehaviour
{
    public Vector2 detectionCenter;  // 検出の中心点(プレイヤーの位置など)
    public float detectionRadius;    // 検出範囲の半径
    public LayerMask enemyLayer;     // 敵を示すレイヤーマスク

    void Update()
    {
        // 指定した範囲内のすべての敵コライダーを検出
        Collider2D[] enemies = Physics2D.OverlapCircleAll(detectionCenter, detectionRadius, enemyLayer);

        // 検出された敵の数とそれぞれの情報をログに出力
        if (enemies.Length > 0)
        {
            Debug.Log("範囲内に検出された敵の数: " + enemies.Length + "体");
            foreach (Collider2D enemy in enemies)
            {
                Debug.Log("検出された敵: " + enemy.name);
            }
        }
        else
        {
            Debug.Log("範囲内に敵は検出されませんでした。");
        }
    }
}

コードの説明:

  • detectionCenterdetectionRadius を使用して、敵の検出範囲を定義しています。これらの値は、プレイヤーの位置やゲームの設定に基づいて調整可能です。
  • enemyLayer は、どの敵を検出対象とするかを定めるレイヤーマスクです。Unityのインスペクターから設定でき、特定の敵だけを対象にすることが可能です。
  • Physics2D.OverlapCircleAll 関数を使って、指定された範囲内にあるすべての敵のコライダーを検出し、配列として結果を得ます。
  • 検出された敵の数と名前を日本語でログ出力します。これにより、デバッグやゲームプレイ中の確認が容易になります。

このコードは特に、プレイヤーの攻撃範囲に敵が入っているかどうかを確認する際に役立ちます。また、エリアベースのイベントや敵の反応を設計する際にも使用できます。

使い方

この「EnemyDetection」スクリプトの使い方について説明します。このスクリプトは、Unityで2Dゲームを開発している際に、プレイヤーの周囲にある敵を検出するために使います。設定と適用のステップは以下の通りです:

ステップ1: スクリプトの準備

まず、Unityプロジェクト内でスクリプトを作成します。UnityエディターのProjectウィンドウで右クリックし、「Create > C# Script」を選択し、「EnemyDetection」と名付けます。スクリプトが作成されたら、ダブルクリックして開き、上記のコードをコピー&ペーストします。

ステップ2: スクリプトの設定

  • detectionCenter: 検出の中心点を設定します。これは通常、プレイヤーの位置やゲーム内の特定のオブジェクトの位置です。スクリプトがアタッチされたオブジェクトの位置を基準にする場合は、transform.positionを利用してこの値を動的に更新することができます。
  • detectionRadius: 検出したい範囲の半径を設定します。この値はゲームのニーズに応じて調整します。
  • enemyLayer: 検出対象となる敵のレイヤーを設定します。Unityのレイヤーシステムを使用して、敵オブジェクトを特定のレイヤーに割り当て、そのレイヤーをここで指定します。

transform.positionを使用して、スクリプトがアタッチされたオブジェクト(通常はプレイヤーキャラクター)の位置を中心に敵を検出するようにするために、EnemyDetectionスクリプトを次のように変更します。この変更により、スクリプトのdetectionCenterが動的に更新され、プレイヤーの現在位置を反映します。

using UnityEngine;

public class EnemyDetection : MonoBehaviour
{
    public float detectionRadius;    // 検出範囲の半径
    public LayerMask enemyLayer;     // 敵を示すレイヤーマスク

    void Update()
    {
        Vector2 detectionCenter = transform.position;  // このオブジェクトの位置を検出の中心として使用

        // 指定した範囲内のすべての敵コライダーを検出
        Collider2D[] enemies = Physics2D.OverlapCircleAll(detectionCenter, detectionRadius, enemyLayer);

        // 検出された敵の数とそれぞれの情報をログに出力
        if (enemies.Length > 0)
        {
            Debug.Log("範囲内に検出された敵の数: " + enemies.Length + "体");
            foreach (Collider2D enemy in enemies)
            {
                Debug.Log("検出された敵: " + enemy.name);
            }
        }
        else
        {
            Debug.Log("範囲内に敵は検出されませんでした。");
        }
    }
}

コードの説明

  • detectionCenter: この変数は、Updateメソッド内で毎フレームtransform.positionに更新されます。これにより、スクリプトがアタッチされたオブジェクトの移動に応じて検出範囲も動的に変わります。
  • detectionRadius: これは、どれだけ広い範囲を検出するかを決定する半径です。この値もゲームのニーズに応じて調整可能です。
  • enemyLayer: 敵がどのレイヤーに属しているかを指定することで、検出を敵に限定します。

このコードは、プレイヤーが移動するたびに周囲の敵を検出するため、特に動的なゲーム環境やリアルタイムの戦闘シナリオに適しています。

ステップ3: スクリプトをオブジェクトにアタッチ

このスクリプトをプレイヤーキャラクターまたはゲーム内の任意のオブジェクトにアタッチします。Unityエディターでオブジェクトを選択し、Inspectorウィンドウで「Add Component」ボタンをクリックして「EnemyDetection」スクリプトを検索し、追加します。

ステップ4: パラメータの調整

Inspectorウィンドウで、detectionCenterdetectionRadiusenemyLayerの各パラメータをゲームの設定に合わせて調整します。enemyLayerは、プロジェクト設定で定義した敵のレイヤーを選択します。

ステップ5: テストとデバッグ

ゲームを実行して、スクリプトが正しく敵を検出しているかを確認します。ログに表示される情報を用いて、検出範囲や敵の配置を調整することができます。

このスクリプトを使用することで、プレイヤーの近くにいる敵を効率的に検出し、それに基づいたアクションをゲーム内で実行することができます。例えば、敵が近くにいるときに警告を表示させたり、特定の攻撃を仕掛けたりすることが可能です。

実際にエディターで構成してみる

上記コードを実装してみましょう
基本の動作になりますので、移動のコードは記述しません

実行結果

まず、どのように検出されているのかを動画でみてみましょう

Sceneウィンドウの敵をマウスで移動させて検出される様子を確認します

シーン構成

検出されたオブジェクトのUI表示

ヒエラルキーのメニューから追加

右上の表示するように位置を調整

敵のシミュレート

ヒエラルキーのメニューから追加

検出用のコライダーをアタッチ
オブジェクトの名前をわかりやすくするためにラベル表示します

プレイヤーのシミュレート

  1. 空のゲームオブジェクトを作成(Playerの位置を想定)
  2. スクリプトをアタッチ
  3. UIのTextMeshProをアウトレット接続
  4. 検出する半径を決める
  5. Enemy LayerをEverythingにする(全てのレイヤーの検出)
    Enemyをエリアしてすることで、特定のレイヤーに所属しているオブジェクトだけ検出できます

スクリプト

using UnityEngine;
using TMPro;  // TextMeshProの名前空間を追加

public class EnemyDetection : MonoBehaviour
{
    public float detectionRadius;    // 検出範囲の半径
    public LayerMask enemyLayer;     // 敵を示すレイヤーマスク
    public TextMeshProUGUI detectedEnemiesText;  // TextMeshProのUI要素

    void Update()
    {
        Vector2 detectionCenter = transform.position;  // このオブジェクトの位置を検出の中心として使用
        string enemiesOutput = "";  // 表示するテキストの初期化

        // 指定した範囲内のすべての敵コライダーを検出
        Collider2D[] enemies = Physics2D.OverlapCircleAll(detectionCenter, detectionRadius, enemyLayer);

        // 検出された敵の数とそれぞれの情報をログに出力
        if (enemies.Length > 0)
        {
            Debug.Log("範囲内に検出された敵の数: " + enemies.Length + "体");
            foreach (Collider2D enemy in enemies)
            {
                Debug.Log("検出された敵: " + enemy.name);
                enemiesOutput += enemy.name + "\n";  // 改行を加えて次の名前を追加
            }
        }
        else
        {
            Debug.Log("範囲内に敵は検出されませんでした。");
            enemiesOutput = "Enemy Not Found";
        }

        detectedEnemiesText.text = enemiesOutput;  // TextMeshProのテキストを更新
    }
    // Gizmosを使用して検出範囲を描画
    void OnDrawGizmos()
    {
        Gizmos.color = Color.red;  // Gizmoの色を赤に設定
        Gizmos.DrawWireSphere(transform.position, detectionRadius);  // 検出範囲を表す円を描画
    }
}

OnDrawGizmosメソッド

このスクリプトをGameObjectにアタッチすると、UnityエディタのSceneビューにて検出範囲が赤い円として表示されます。Gizmos.colorを変更することで、円の色を変えることができます。

OnDrawGizmos メソッドは、Unity エディタ内でのみ動作し、ゲームがビルドされて実行される際には影響を与えません。OnDrawGizmos はデバッグ時に視覚的なヘルプを提供するために設計されており、ビルドプロセス中には完全に無視されます。これは、実際のゲームプレイにおいて余分な処理リソースを消費することなく、開発中に必要な情報をエディタで確認できるようにするための便利な機能です。

したがって、OnDrawGizmos を使用しても、アプリケーションのパフォーマンスには影響せず、ビルド時に問題が生じることはありません。デバッグ目的でのみ機能し、リリースビルドでは何の効果も及ぼさないため、安心して使用できます。

ラベルやチェック用の円が表示されない場合

Unity

Posted by hidepon