2026-05-18 버그 수정

This commit is contained in:
2026-05-18 17:59:13 +09:00
parent 67cedd8ad2
commit 80cf41af2a
19 changed files with 596 additions and 17 deletions

View File

@@ -0,0 +1,132 @@
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
[Header("Spawn Configuration")]
[SerializeField] private Enemy _enemyPrefab;
[SerializeField] private int _maxAliveCount = 3;
[SerializeField] private float _spawnInterval = 2f;
[SerializeField] private float _initialDelay = 0f;
[Header("Spawn Position")]
[SerializeField] private Transform[] _spawnPoints;
[SerializeField] private float _spawnRadius = 0f;
[SerializeField] private Transform _enemyParent;
[Header("Behavior")]
[SerializeField] private bool _spawnOnStart = true;
[SerializeField] private bool _respawnOnDeath = true;
[SerializeField] private int _totalSpawnLimit = 0;
private readonly List<Enemy> _aliveEnemies = new();
private float _nextSpawnTime;
private int _totalSpawned;
private bool _active;
private void Start()
{
if (_spawnOnStart) BeginSpawning();
}
public void BeginSpawning()
{
_active = true;
_nextSpawnTime = Time.time + _initialDelay;
}
public void StopSpawning() => _active = false;
public void ResetSpawner()
{
for (int i = _aliveEnemies.Count - 1; i >= 0; i--)
{
if (_aliveEnemies[i] != null)
Destroy(_aliveEnemies[i].gameObject);
}
_aliveEnemies.Clear();
_totalSpawned = 0;
_nextSpawnTime = Time.time + _initialDelay;
}
private void Update()
{
if (!_active) return;
_aliveEnemies.RemoveAll(e => e == null);
if (!_respawnOnDeath && _aliveEnemies.Count == 0 && _totalSpawned > 0) return;
if (_totalSpawnLimit > 0 && _totalSpawned >= _totalSpawnLimit) return;
if (_aliveEnemies.Count >= _maxAliveCount) return;
if (Time.time < _nextSpawnTime) return;
if (_enemyPrefab == null) return;
SpawnOne();
_nextSpawnTime = Time.time + _spawnInterval;
}
public Enemy SpawnOne()
{
if (_enemyPrefab == null) return null;
Vector3 spawnPos = GetSpawnPosition();
Enemy enemy = Instantiate(_enemyPrefab, spawnPos, Quaternion.identity, _enemyParent);
_aliveEnemies.Add(enemy);
_totalSpawned++;
return enemy;
}
private Vector3 GetSpawnPosition()
{
Vector3 basePos;
if (_spawnPoints != null && _spawnPoints.Length > 0)
{
Transform pick = _spawnPoints[Random.Range(0, _spawnPoints.Length)];
basePos = pick != null ? pick.position : transform.position;
}
else
{
basePos = transform.position;
}
if (_spawnRadius > 0f)
{
Vector2 offset = Random.insideUnitCircle * _spawnRadius;
basePos.x += offset.x;
basePos.y += offset.y;
}
return basePos;
}
private void OnDrawGizmosSelected()
{
Color pointColor = Color.cyan;
Color radiusColor = new Color(0f, 1f, 1f, 0.25f);
if (_spawnPoints != null && _spawnPoints.Length > 0)
{
foreach (var p in _spawnPoints)
{
if (p == null) continue;
Gizmos.color = pointColor;
Gizmos.DrawWireSphere(p.position, 0.3f);
if (_spawnRadius > 0f)
{
Gizmos.color = radiusColor;
Gizmos.DrawWireSphere(p.position, _spawnRadius);
}
}
}
else
{
Gizmos.color = pointColor;
Gizmos.DrawWireSphere(transform.position, 0.3f);
if (_spawnRadius > 0f)
{
Gizmos.color = radiusColor;
Gizmos.DrawWireSphere(transform.position, _spawnRadius);
}
}
}
}