Week03_EnemySpawning - M-634/unity-game-dev-tutorial GitHub Wiki

🎯 今回のゴール

  • 敵キャラクター(Enemy)を一定間隔で出現させる
  • 敵がプレイヤーに向かって移動するAIを作る
  • C# の配列(Array)の基本と Unity での使い方を理解する
  • Tag を使ってオブジェクトを分類する

🧭 授業の流れ

① 敵のプレハブを作成

  • Assets/_Workspace/Prefabs/Enemy.prefab を作成

② 敵のスポーン処理を実装

📄 EnemySpawner.cs

using UnityEngine;

public class EnemySpawner : MonoBehaviour
{
    [SerializeField]
    private GameObject _enemyPrefab;
    
    [SerializeField] 
    private float _spawnInterval = 2f;
    
    [SerializeField]
    private Transform[] _spawnPoints;

    private float _timer;

    void Update()
    {
        _timer += Time.deltaTime;

        if (_timer >= _spawnInterval)
        {
            int rand = Random.Range(0, _spawnPoints.Length);
            Instantiate(_enemyPrefab, _spawnPoints[rand].position, Quaternion.identity);
            _timer = 0f;
        }
    }
}

✅ ### ## セットアップ手順

  1. 空の GameObject「EnemySpawner」を作成
  2. 子オブジェクトとして SpawnPoint1〜4 を作成(画面外などに配置)
  3. EnemySpawner.cs を「EnemySpawner」にアタッチし、enemyPrefab と spawnPoints[] にそれぞれ設定

③敵の移動AIを実装

📄 EnemyAI.cs

using UnityEngine;

public class EnemyAI : MonoBehaviour
{
    [SerializeField] 
    private float _moveSpeed = 3f;

    private Transform _player;

    void Start()
    {
        GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
        if (playerObj == null)
        {
            throw new NullReferenceException("playerObj is null");
        }
            
        _player = playerObj.transform;
    }

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

        Vector2 direction = (_player.position - transform.position).normalized;
        transform.position += (Vector3)(direction * _moveSpeed * Time.deltaTime);
    }
}

✅ ポイント

プレイヤーに向かって直進する単純なAI

Tag を使ってプレイヤーを自動で見つける

✅ 動作確認

敵が一定間隔でランダムな位置に出現するか?

敵がプレイヤーに向かってまっすぐ移動してくるか?

Player に「Player」タグが設定されているか確認!


⚠️ よくあるミスと対策

問題 原因と対処 敵が動かない Player にタグが設定されていない 敵が出てこない spawnPoints[] の設定漏れ


📘 補足:C# の配列とは?

Unityでは、**同じ種類のオブジェクトをまとめて扱うときに配列(Array)**を使います。

🔹 宣言と使い方

[SerializeField]
 private Transform[] _spawnPoints;
Transform point = _spawnPoints[0]; // 最初のスポーン位置
int count = _spawnPoints.Length; // 登録されたスポーン数

🔹 Unity Inspectorでの設定 配列に要素数を入力

ゲームオブジェクトをドラッグ&ドロップで登録できる

📘 補足:List型(リスト)とは?

List は柔軟なコレクション。要素の追加・削除が可能で、リアルタイムに扱いたいデータに向いています。

🔹 宣言と使い方

using System.Collections.Generic;

[SerializeField] 
private List<GameObject> _enemyTypes;

void SpawnRandomEnemy()
{
    int index = Random.Range(0, _enemyTypes.Count);
    Instantiate(_enemyTypes[index], transform.position, Quaternion.identity);
}
比較項目 配列(Array) List(リスト)
要素数変更 ❌ 不可 ✅ 可能(Add / Remove)
Inspector表示 ✅ [SerializeField] ✅ [SerializeField]が必要

💡 課題(宿題)

1.敵の種類を追加してみよう!

  • 新しい見た目・スピードの敵プレハブをもう1つ作成

2.敵の向きが常にプレイヤーの方向に向けるようにしよう

  • Enemy.prefabの 「Scale = x」を「-1」or 「1」にすると...

Transformのscaleを変える方法例

transform.localScale = new Vector3(1, 1, 1);

3.出てきた敵を倒してみる

  • Week02の資料等を参考に、敵に弾をあてて「EnemyPrefab」をDestroyしてみる
⚠️ **GitHub.com Fallback** ⚠️