2026-05-18 버그 수정
This commit is contained in:
132
Assets/02_Scripts/Enemy/EnemySpawner.cs
Normal file
132
Assets/02_Scripts/Enemy/EnemySpawner.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user