Unityで「ヴァンパイヤ・サバイバー」のように、フィールド上に敵がランダムに出現する機能を実装したいと思いました。
今回は必要最低限の機能を実装したので備忘録です。
完成イメージ
今回は、ゲームの理解のために、必要最低限の機能だけに絞っています。
- 敵が主人公から一定距離の円周上にランダムに出現します。
- 出現した敵は主人公に向かって移動します。
- 一定時間ごとに敵が出現します。
この3つに絞ります。
手順
1. 敵のプレハブを作成
まずは、敵となるキャラクターのプレハブを作成します。
- ゲームオブジェクトの作成: Hierarchyビューで右クリック -> 2D Object -> Sprites -> Circle(または任意のSprite)を選択して、敵のベースとなるゲームオブジェクトを作成します。
- Sprite Rendererの設定: Inspectorビューで、Sprite Rendererコンポーネントを追加し、敵の見た目となるスプライトを設定します。
- Collider 2Dの追加: 当たり判定を設定するために、Collider 2Dコンポーネント(例:Circle Collider 2D)を追加します。
- プレハブ化: 作成した敵のゲームオブジェクトをProjectビューにドラッグ&ドロップしてプレハブ化します。
2. 敵の動きを制御するスクリプト(EnemyController.cs)
次に、敵が主人公に向かって移動するためのC#スクリプトを作成します。
- 新規C#スクリプトの作成: Projectビューで右クリック -> Create -> C# Script を選択し、EnemyControllerという名前のスクリプトを作成します。
- コードの記述: 作成したEnemyController.csをエディタで開き、以下のコードを記述します。
using UnityEngine;
public class EnemyController : MonoBehaviour
{
    public float speed = 2f; // 敵の移動速度
    private Transform player; // 主人公のTransform
    void Start()
    {
        // 主人公のゲームオブジェクトを探してTransformを取得
        player = GameObject.FindGameObjectWithTag("Player").transform;
    }
    void Update()
    {
        if (player != null)
        {
            // 主人公の方向を計算
            Vector2 direction = (player.position - transform.position).normalized;
            // 主人公に向かって移動
            transform.position = Vector2.MoveTowards(transform.position, player.position, speed * Time.deltaTime);
            // 敵の向きを主人公の方向に向ける (オプション)
            float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
            transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        }
    }
}
コード解説
- speed: 敵の移動速度を調整する変数です。
- player: 主人公のTransformを格納する変数です。- Start()メソッド内で、”Player”タグが付いたゲームオブジェクトを探して、そのTransformを取得します。忘れずに主人公のゲームオブジェクトに”Player”タグを設定してください。
- Update(): 毎フレーム呼ばれ、敵を主人公に向かって移動させます。- Vector2.MoveTowards(): 現在位置から目標位置に向かって、一定速度で移動させる関数です。
- transform.rotation: 敵の向きを主人公の方向に向けるためのオプションのコードです。スプライトの向きによっては調整が必要です。
 
- スクリプトのアタッチ: 作成したEnemyController.csを、先ほど作成した敵のプレハブにドラッグ&ドロップしてアタッチします。
3. 敵を出現させるスクリプト(EnemySpawner.cs)
最後に、敵を円周上にランダムに出現させるためのC#スクリプトを作成します。
- 新規C#スクリプトの作成: Projectビューで右クリック -> Create -> C# Script を選択し、EnemySpawnerという名前のスクリプトを作成します。
- コードの記述: 作成したEnemySpawner.csをエディタで開き、以下のコードを記述します。
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
    public GameObject enemyPrefab; // 出現させる敵のプレハブ
    public float spawnRadius = 5f; // 出現させる円の半径
    public float spawnInterval = 2f; // 出現間隔(秒)
    private Transform player; // 主人公のTransform
    void Start()
    {
        // 主人公のゲームオブジェクトを探してTransformを取得
        player = GameObject.FindGameObjectWithTag("Player").transform;
        // 一定時間ごとに敵を出現させる
        InvokeRepeating("SpawnEnemy", 0f, spawnInterval);
    }
    void SpawnEnemy()
    {
        if (player != null)
        {
            // 主人公の位置を中心に円周上のランダムな位置を計算
            Vector2 randomCirclePoint = Random.insideUnitCircle.normalized * spawnRadius;
            Vector3 spawnPosition = player.position + new Vector3(randomCirclePoint.x, randomCirclePoint.y, 0f);
            // 敵を出現させる
            Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
        }
    }
}
コード解説
- enemyPrefab: 出現させる敵のプレハブを設定します。インスペクターから設定してください。
- spawnRadius: 敵を出現させる円の半径を設定します。
- spawnInterval: 敵を出現させる時間間隔(秒)を設定します。
- player: 主人公のTransformを格納する変数です。- Start()メソッド内で、”Player”タグが付いたゲームオブジェクトを探して、そのTransformを取得します。
- Start():- InvokeRepeating()を使って、- SpawnEnemy()関数を一定時間ごとに呼び出します。
- SpawnEnemy(): 敵を出現させる関数です。- Random.insideUnitCircle: 半径1の単位円内のランダムな点を返します。- .normalizedでその点を単位円の円周上に移動させ、- spawnRadiusを掛けることで指定した半径の円周上の点にします。
- Instantiate(): 敵のプレハブを- spawnPositionの位置に出現させます。
 
- スクリプトのアタッチ: Hierarchyビューで右クリック -> Create Empty で空のゲームオブジェクトを作成し、EnemySpawnerと名前を付けます。作成したEnemySpawner.csをこのゲームオブジェクトにアタッチします。
4. 設定の確認と調整
- 主人公に”Player”タグを付ける: 主人公のゲームオブジェクトを選択し、Inspectorビューでタグを”Player”に設定します。
- EnemySpawnerの設定:- EnemySpawnerゲームオブジェクトのInspectorビューで、- Enemy Prefabに作成した敵のプレハブをドラッグ&ドロップして設定します。
- パラメータの調整: spawnRadius、spawnInterval、EnemyControllerのspeedなどを、ゲームの難易度に合わせて調整します。
- (必要に応じて)敵のRigidbody2Dの設定: 敵のプレハブにRigidbody2Dコンポーネントを追加し、Gravity Scaleを0にして重力の影響をなくします。また、Is Kinematicを有効にして、物理演算の影響を受けないようにします。
これで、敵が円周上にランダムに出現し、主人公を追尾するようになりました!
 
  
  
  
  
