Prefab
Prefab là mẫu thiết kế sẵn (template asset) trong Unity — tạo một lần, nhân bản vô số lần. Sửa Prefab gốc sẽ cập nhật mọi instance còn kế thừa thuộc tính đó.
Hãy tưởng tượng...
Prefab giống như khuôn đúc bánh mì. Bạn thiết kế khuôn (Prefab gốc) một lần với đầy đủ nhân liệu. Sau đó, đổ bột vào khuôn (Instantiate()) để cho ra hàng trăm chiếc bánh giống hệt nhau trong tích tắc. Nếu cần thay đổi hương vị — chỉnh khuôn gốc — tất cả mẻ bánh tiếp theo đều có hương vị mới.
Khái niệm chi tiết
Prefab là file .prefab lưu trữ toàn bộ cấu trúc một GameObject — tất cả
Components, thiết lập và Child objects. Khi kéo Prefab vào Scene, Unity tạo ra một
Prefab Instance kết nối với Prefab gốc.
Prefab Overrides: mỗi Instance có thể ghi đè (override) một số thuộc tính riêng (màu sắc, HP…) trong khi vẫn kế thừa phần còn lại từ Prefab gốc. Khi Prefab gốc cập nhật, Instance không có override tự động nhận bản mới.
Nested Prefabs: Prefab có thể chứa Prefab khác bên trong. Rất hữu ích cho Level Prefab chứa Room Prefabs, mỗi Room chứa Enemy Prefabs.
Gọi Instantiate()/Destroy() liên tục gây lag (Garbage Collection
spikes). Với tốc độ cao (đạn súng máy, hiệu ứng…) hãy dùng
Object Pooling.
Sơ đồ: Prefab → Instances
📦 Prefab Asset
Enemy_Goblin.prefab
⚙ Rigidbody · ⚙ Collider · ⚙ EnemyAI
HP: 100 · Speed: 3
Instance #1
pos: (2, 0, 5)
HP: 100 (gốc)
Instance #2 — Override
pos: (-3, 0, 7)
HP: 150 ← Override!
Instance #3
pos: (0, 0, 10)
HP: 100 (gốc)
Hướng dẫn thực hành
Tạo Prefab từ Scene
Thiết kế xong → kéo từ Hierarchy vào thư mục Assets trong Project window.
Chỉnh sửa trong Prefab Mode
Double-click file .prefab → môi trường chỉnh sửa cô lập. Thay đổi lan ra tất cả Instances.
Kéo vào [SerializeField]
Trong Inspector, kéo file Prefab từ Project vào biến để script dùng Instantiate.
Apply Override lên Prefab gốc
Chọn Instance → Inspector → Overrides → Apply All.
Trình mô phỏng tương tác
Chọn loại Prefab, nhấn Instantiate để tạo bản sao. Click vào một Instance để chọn và thay đổi Override. Nhấn Destroy để xóa nó.
Nhấn "Instantiate()" để tạo GameObject từ Prefab
Inspector
Chọn một Instance
Ví dụ Code
Cơ bảnusing UnityEngine;
public class PrefabSpawner : MonoBehaviour
{
[SerializeField] private GameObject enemyPrefab;
[SerializeField] private Transform spawnPoint;
void Start()
{
// Tạo bản sao tại vị trí và góc của spawnPoint
GameObject clone = Instantiate(
enemyPrefab, spawnPoint.position, spawnPoint.rotation
);
// Lấy component từ bản sao và cấu hình ngay
EnemyAI ai = clone.GetComponent<EnemyAI>();
if (ai != null)
{
ai.patrolSpeed = 3f;
ai.detectionRange = 8f;
}
clone.name = $"Enemy_{Random.Range(100, 999)}";
}
}Ví dụ Code
Nâng caousing System.Collections;
using UnityEngine;
public class WaveSpawner : MonoBehaviour
{
[SerializeField] private GameObject[] enemyPrefabs; // nhiều loại kẻ thù
[SerializeField] private Transform[] spawnPoints; // nhiều điểm sinh
[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++)
{
// Chọn Prefab và SpawnPoint ngẫu nhiên
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);
}
}
}📌 Ghi nhớ nhanh
- ▸Prefab = mẫu thiết kế, tạo một lần dùng mãi mãi
- ▸Instance có thể Override thuộc tính riêng
- ▸Chỉnh Prefab gốc → tất cả Instance tự cập nhật
- ▸Spawn liên tục → dùng Object Pooling thay Instantiate/Destroy
⚠️ Lỗi thường gặp
❌ Instantiate không lưu tham chiếu
Tạo xong không biết bản sao đó ở đâu để điều khiển
✅ var clone = Instantiate(prefab);
❌ Gọi Instantiate/Destroy liên tục trong game loop
GC spikes, memory lag, đặc biệt khi spawn đạn súng máy
✅ Object Pool: tạo sẵn, bật/tắt thay vì tạo/xóa