Projext/Assets/Scripts/Enemy/Spawner/Monster Spwaner.cs

92 lines
3.2 KiB
C#
Raw Normal View History

2026-02-02 08:30:23 +00:00
using UnityEngine;
public class MonsterSpawner : MonoBehaviour
{
[Header("--- 몹 스폰 설정 ---")]
2026-02-02 15:02:12 +00:00
[SerializeField] private string mobTag = "NormalMob";
[SerializeField] private float spawnRange = 25f; // 플레이어 감지 범위 (조금 늘림)
[SerializeField] private float respawnCooldown = 3f; // 죽었을 때만 적용되는 쿨타임
2026-02-02 08:30:23 +00:00
private GameObject _myMonster;
private MonsterClass _monsterScript;
private Transform _player;
private float _nextSpawnTime;
private void Start()
{
FindPlayer();
}
private void Update()
{
2026-02-02 15:02:12 +00:00
if (_player == null) { FindPlayer(); return; }
2026-02-02 08:30:23 +00:00
float dist = Vector3.Distance(transform.position, _player.position);
// 1. 플레이어가 범위 안에 들어왔을 때
if (dist <= spawnRange)
{
2026-02-02 15:02:12 +00:00
// ⭐ [수정] 쿨타임이 지났고, 몹이 없거나 꺼져있다면 '재활성화' 시도
2026-02-02 08:30:23 +00:00
if (Time.time >= _nextSpawnTime && (_myMonster == null || !_myMonster.activeSelf))
{
SpawnMonster();
}
}
2026-02-02 15:02:12 +00:00
// 2. 플레이어가 범위 밖으로 나갔을 때
2026-02-02 08:30:23 +00:00
else
{
DespawnMonster();
}
}
private void FindPlayer()
{
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
if (playerObj != null) _player = playerObj.transform;
}
private void SpawnMonster()
{
2026-02-02 15:02:12 +00:00
// ⭐ [핵심] 기존에 소환된 몹이 있고, 죽은 게 아니라면 단순히 켜기만 합니다!
if (_myMonster != null && _monsterScript != null && !_monsterScript.IsDead)
{
_myMonster.SetActive(true); // HP와 위치가 그대로 유지된 채로 켜집니다.
return;
}
// ⭐ 아예 처음 소환하거나, 죽어서 새로 뽑아야 할 때만 풀에서 가져옵니다.
2026-02-02 08:30:23 +00:00
_myMonster = GenericObjectPool.Instance.SpawnFromPool(mobTag, transform.position, transform.rotation);
if (_myMonster != null)
{
_monsterScript = _myMonster.GetComponent<MonsterClass>();
2026-02-02 15:02:12 +00:00
// ❌ OnEnable에서 피가 안 채워지므로, 여기서 새로 태어났음을 알립니다.
_monsterScript.ResetStats();
2026-02-02 08:30:23 +00:00
}
}
private void DespawnMonster()
{
if (_myMonster != null && _myMonster.activeSelf)
{
2026-02-02 15:02:12 +00:00
// 몹이 살아있다면 풀로 돌려보내지 않고 그 자리에서 SetActive(false)만 합니다.
2026-02-02 08:30:23 +00:00
if (_monsterScript != null && !_monsterScript.IsDead)
{
_myMonster.SetActive(false);
2026-02-02 15:02:12 +00:00
// _nextSpawnTime을 갱신하지 않으므로 다시 범위에 들어오면 즉시 켜집니다.
2026-02-02 08:30:23 +00:00
}
2026-02-02 15:02:12 +00:00
// 몹이 진짜 죽었다면 참조를 비우고 쿨타임을 적용합니다.
2026-02-02 08:30:23 +00:00
else if (_monsterScript != null && _monsterScript.IsDead)
{
_nextSpawnTime = Time.time + respawnCooldown;
2026-02-02 15:02:12 +00:00
_myMonster = null; // 다음엔 새로 뽑아야 함
2026-02-02 08:30:23 +00:00
}
}
}
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, spawnRange);
}
}