Prefab
Prefab은 한 번 설계해 여러 번 스폰하는 재사용 Unity 템플릿 에셋입니다. Instantiate로 인스턴스를 만들고 Overrides·Nested Prefab·Object Pooling 기초를 배웁니다. Prefab Mode와 Apply까지 다루는 입문 가이드입니다.
상상해 보세요...
Prefab은 빵 틀과 같습니다. 재료가 담긴 틀(Prefab 에셋)을 한 번 만들고, 반죽을 부어(Instantiate()) 몇 초 만에 똑같은 빵 수백 개를 얻습니다. 새 맛이 필요하면 틀을 수정하세요——이후 배치가 모두 그 변경을 따릅니다.
개념 자세히
Prefab은 GameObject 계층 전체——Component·설정·자식——를 담는 .prefab 파일입니다.
Scene에 드래그하면 Unity가 그 에셋에 연결된
Prefab Instance를 만듭니다.
Prefab Overrides: 각 Instance는 선택한 속성 (색, HP…)만 덮어쓰고 나머지는 상속합니다. Prefab 에셋이 갱신되면 Override가 없는 인스턴스는 새 값을 자동으로 받습니다.
Nested Prefabs: Prefab 안에 다른 Prefab을 넣을 수 있습니다. Room Prefab을 담은 Level Prefab, 그 Room에 Enemy Prefab을 두는 식입니다.
짧은 루프에서 Instantiate()/Destroy()를 반복하면
(GC 스파이크) 렉이 납니다. 고빈도 스폰(기관총 탄환, VFX…)에는
Object Pooling을 쓰세요.
다이어그램: Prefab → Instances
📦 Prefab Asset
Enemy_Goblin.prefab
⚙ Rigidbody · ⚙ Collider · ⚙ EnemyAI
HP: 100 · Speed: 3
Instance #1
pos: (2, 0, 5)
HP: 100 (Prefab 원본)
Instance #2 — Override
pos: (-3, 0, 7)
HP: 150 ← Override!
Instance #3
pos: (0, 0, 10)
HP: 100 (Prefab 원본)
실습 단계
Scene에서 Prefab 만들기
설정을 마친 뒤 Hierarchy에서 Project 창의 Assets 폴더로 드래그합니다.
Prefab Mode에서 편집
.prefab를 더블클릭 → 격리된 편집 공간. 변경이 모든 Instance에 전파됩니다.
[SerializeField]로 할당
Inspector에서 Project의 Prefab 에셋을 필드에 드래그해 스크립트가 Instantiate할 수 있게 합니다.
Overrides를 Prefab 에셋에 Apply
Instance 선택 → Inspector → Overrides → Apply All.
인터랙티브 시뮬레이터
Prefab 타입을 고르고 Instantiate로 복제하세요. Instance를 클릭해 Override를 바꾸고 Destroy로 제거해 보세요.
"Instantiate()"로 Prefab에서 GameObject 생성
Inspector
Instance를 선택하세요
코드 예제
기본using UnityEngine;
public class PrefabSpawner : MonoBehaviour
{
[SerializeField] private GameObject enemyPrefab;
[SerializeField] private Transform spawnPoint;
void Start()
{
// Spawn a copy at the spawnPoint pose
GameObject clone = Instantiate(
enemyPrefab, spawnPoint.position, spawnPoint.rotation
);
// Configure the clone immediately
EnemyAI ai = clone.GetComponent<EnemyAI>();
if (ai != null)
{
ai.patrolSpeed = 3f;
ai.detectionRange = 8f;
}
clone.name = $"Enemy_{Random.Range(100, 999)}";
}
}코드 예제
고급using System.Collections;
using UnityEngine;
public class WaveSpawner : MonoBehaviour
{
[SerializeField] private GameObject[] enemyPrefabs; // multiple enemy types
[SerializeField] private Transform[] spawnPoints; // multiple spawn points
[SerializeField] private int enemiesPerWave = 5;
[SerializeField] private float spawnInterval = 0.5f;
[SerializeField] private float waveCooldown = 5f;
private int _waveCount = 0;
void Start() => StartCoroutine(SpawnLoop());
private IEnumerator SpawnLoop()
{
while (true)
{
_waveCount++;
for (int i = 0; i < enemiesPerWave; i++)
{
// Pick a Prefab and SpawnPoint at random
var prefab = enemyPrefabs[Random.Range(0, enemyPrefabs.Length)];
var point = spawnPoints[Random.Range(0, spawnPoints.Length)];
Instantiate(prefab, point.position, point.rotation);
yield return new WaitForSeconds(spawnInterval);
}
yield return new WaitForSeconds(waveCooldown);
}
}
}📌 빠른 정리
- ▸Prefab = 재사용 템플릿——한 번 설계, 계속 사용
- ▸Instance는 개별 속성을 Override할 수 있음
- ▸Prefab 에셋 편집 → 연결된 모든 Instance 갱신
- ▸고빈도 스폰 → Instantiate/Destroy 대신 Object Pooling
⚠️ 흔한 실수
❌ 참조를 남기지 않고 Instantiate
스폰은 했지만 나중에 그 클론을 제어할 수 없음
✅ var clone = Instantiate(prefab);
❌ 핫 루프에서 매 프레임 Instantiate/Destroy
GC 스파이크와 끊김——특히 기관총 탄환
✅ Object Pool: 미리 만들고 enable/disable