본문으로 건너뛰기

스폰 시스템

가중치 기반 랜덤 스폰, 최대 생존 수, 인터벌, 반경을 SpawnGroup ScriptableObject로 설정합니다. Spawner를 여러 개 배치해 각각 독립적으로 운용합니다.

구조

SpawnSystem (순수 C# 인스턴스)
— 씬 내 모든 Spawner 등록 관리

SpawnGroup (ScriptableObject)
— Entry 목록 (Prefab + Weight + Min/MaxCount)
— SpawnInterval, MaxAlive, SpawnRadius

Spawner (MonoBehaviour)
— SpawnGroup을 사용해 실제 생성/파괴 처리

빠른 시작

1. SpawnGroup 에셋 만들기

Create → AchUtils/Spawn/Spawn Group

SpawnInterval : 5 ← 5초마다 스폰 시도
MaxAlive : 10 ← 최대 10마리 동시 존재
SpawnRadius : 8 ← 스포너 중심 반경 8m

Entries:
[0] Prefab: SlimeBlue Weight: 70 Min: 1 Max: 2
[1] Prefab: SlimeRed Weight: 25 Min: 1 Max: 1
[2] Prefab: SlimeBoss Weight: 5 Min: 1 Max: 1

2. Spawner 배치

씬에 빈 오브젝트를 만들고 Spawner 컴포넌트를 추가합니다.

필드설명
GroupSpawnGroup 에셋
Auto Start씬 시작 시 자동으로 스폰 시작

3. 스폰 제어

using AchUtils.Spawn;

[SerializeField] Spawner spawner;

// 시작 / 중지
spawner.StartSpawning();
spawner.StopSpawning();

// 전체 제거
spawner.DespawnAll();

// 이벤트
spawner.OnSpawned += obj => Debug.Log($"{obj.name} 스폰");
spawner.OnDespawned += obj => Debug.Log($"{obj.name} 제거");

4. SpawnSystem으로 전체 제어

[SerializeField] Spawner[] spawners;

private SpawnSystem spawnSystem;

void Awake()
{
spawnSystem = new SpawnSystem(spawners);
}

// 모든 스포너 시작 / 중지
spawnSystem.StartAll();
spawnSystem.StopAll();
spawnSystem.DespawnAll();

API

Spawner

bool IsSpawning
IReadOnlyList<GameObject> AliveObjects

void StartSpawning()
void StopSpawning()
void DespawnAll()

event Action<GameObject> OnSpawned
event Action<GameObject> OnDespawned

SpawnSystem

SpawnSystem()
SpawnSystem(IEnumerable<Spawner> spawners)

void RegisterSpawner(Spawner spawner)
void UnregisterSpawner(Spawner spawner)

void StartAll()
void StopAll()
void DespawnAll()

IReadOnlyList<Spawner> Spawners

SpawnGroup.Entry

GameObject Prefab
float Weight // 가중치 (높을수록 자주 선택)
int MinCount // 1회 스폰 시 최소 수
int MaxCount // 1회 스폰 시 최대 수

스폰 로직

  1. SpawnInterval마다 실행
  2. 현재 생존 수 < MaxAlive인 경우 PickRandom()으로 Entry 선택
  3. Random.Range(Min, Max+1)개 생성
  4. SpawnRadiusRandom.insideUnitCircle 위치에 배치
// 직접 가중치 선택 로직 사용
SpawnGroup.Entry entry = spawnGroup.PickRandom();
var obj = Instantiate(entry.Prefab, spawnPos, Quaternion.identity);

다중 스포너 예시

DungeonSpawner → SlimeGroup (5마리, 3초)
BossRoomSpawner → EliteGroup (2마리, 10초)
TreasureSpawner → ChestGroup (1마리, 30초)

각 Spawner는 독립 인스턴스이므로 서로 다른 SpawnGroup과 설정을 가질 수 있습니다.

::: tip 풀링 스폰 빈도가 높다면 Object Pooling과 연계하세요. Spawner.OnSpawned / OnDespawned 이벤트에서 풀 반납 로직을 추가할 수 있습니다. :::