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
を有効にして、物理演算の影響を受けないようにします。
これで、敵が円周上にランダムに出現し、主人公を追尾するようになりました!