using UnityEngine; using System.Collections; using System.Collections.Generic; [System.Serializable] // 이 속성이 있어야 인스펙터에 노출됩니다. public class Wave { public string waveName; // 웨이브 식별용 이름 public GameObject enemyPrefab; // 소환할 적 프리팹 public int count; // 소환할 마릿수 public float spawnRate; // 적 한 마리당 소환 간격 (초) } public class WaveManager : MonoBehaviour { [Header("Wave Settings")] [SerializeField] private List waves; // 웨이브 데이터 리스트 [SerializeField] private float timeBetweenWaves = 5f; // 웨이브 간 대기 시간 [SerializeField] private Transform[] spawnPoints; // 적이 나타날 위치들 private Transform _target; private int _currentWaveIndex = 0; void Start() { _target = GameObject.FindWithTag("Core").transform; // 게임 시작 시 웨이브 루틴 시작 StartCoroutine(StartWaveRoutine()); } IEnumerator StartWaveRoutine() { // 실행하는 오브젝트의 이름과 고유 ID를 출력 Debug.Log($"[{gameObject.name} : {gameObject.GetInstanceID()}] 코루틴 가동 시작. 총 웨이브: {waves.Count}"); while (_currentWaveIndex < waves.Count) { Wave currentWave = waves[_currentWaveIndex]; Debug.Log($"현재 인덱스: {_currentWaveIndex}, 웨이브명: {currentWave.waveName}"); for (int i = 0; i < currentWave.count; i++) { SpawnEnemy(currentWave.enemyPrefab); yield return new WaitForSeconds(currentWave.spawnRate); } _currentWaveIndex++; // 여기서 인덱스를 올림 yield return new WaitForSeconds(timeBetweenWaves); } Debug.Log($"[{gameObject.name}] 모든 웨이브 종료"); } void SpawnEnemy(GameObject enemyPrefab) { // 1. 스폰 위치 선택 Transform spawnPoint = spawnPoints[Random.Range(0, spawnPoints.Length)]; // 2. 방향 계산 (Core - SpawnPoint) Vector3 directionToCore = (_target.position - spawnPoint.position).normalized; // 3. 방향을 Quaternion 회전값으로 변환 (Y축 기준으로만 회전하도록 설정) // 윗방향(Vector3.up)을 축으로 하여 해당 방향을 바라보게 함 Quaternion lookRotation = Quaternion.LookRotation(new Vector3(directionToCore.x, 0, directionToCore.z)); // 4. 계산된 위치와 회전값으로 생성 Instantiate(enemyPrefab, spawnPoint.position, lookRotation); } }