U
12 / 22 · 8 phút
Hỏi đáp

Prefab: cái file, các bản sao, và những chỗ sửa ở giữa

câu trả lời ngắn

Prefab trong Unity là gì?

Prefab là một GameObject được lưu thành file trong bảng Project; các bản nằm trong cảnh đều bám theo nó, nên sửa file là đổi hết một lượt. Còn sửa một bản thì thay đổi đó chỉ là override của riêng bản ấy — hiện ở dạng chữ đậm, kèm Apply All và Revert All trong nút Overrides.

Prefab là một GameObject được lưu thành file. Những bản bạn thả vào cảnh không phải bản sao của nhau — tất cả đều bám theo đúng file đó, nên sửa file là sửa hết một lượt. Ý tưởng chỉ có vậy, và mọi rối rắm quanh prefab đều xuất phát từ một câu hỏi: mình đang sửa cái file, hay sửa một bản của nó?

Tạo một prefab

  1. 1

    Dựng vật thể trong cảnh cho tới khi nó đúng ý bạn: mesh, material, collider, script, các object con, đủ cả.

  2. 2

    Kéo nó từ Hierarchy vào một thư mục trong bảng Project. Tên nó trong Hierarchy chuyển sang màu xanh: bản đó giờ là một instance của một file trên ổ cứng.

  3. 3

    Kéo file đó trở lại cảnh bao nhiêu lần tuỳ bạn. Hai mươi kẻ địch, một file duy nhất.

Sửa cái file, chứ không sửa một bản

Bấm đúp vào prefab trong bảng Project, Unity mở Prefab Mode: chỉ mình vật thể đó, trên một sân khấu trống, không có gì khác cản đường. Sửa gì ở đó là sửa chính file, nên mọi instance trong mọi cảnh đều đi theo ngay lập tức.

  • Còn nếu sửa thẳng một instance trong cảnh, bạn tạo ra một override: đúng thuộc tính đó, trên đúng bản đó, từ giờ phớt lờ file gốc. Inspector hiện nó ở dạng chữ đậm kèm vạch xanh ở lề.

  • Nút Overrides ở đầu Inspector liệt kê tất cả chúng, kèm hai nút đáng giá nhất: Apply All để ghi ngược vào file, và Revert All để vứt hết đi.

  • Override không phải là lỗi. Một điểm tuần tra, một tốc độ, một màu sắc khác nhau ở từng bản chính là công dụng của nó — nhưng một bản có ba chục override thì chỉ còn là prefab trên danh nghĩa.

Variant, cho con quái gần giống hệt

Prefab Variant là một prefab dựa trên một prefab khác: nó giữ nguyên mọi thứ của bản cha và chỉ đổi vài chỗ. Làm một Enemy gốc, rồi một variant Fast Enemy chỉ đổi tốc độ và màu — sửa lỗi ở bản gốc là cả hai cùng hết lỗi.

  • Bấm chuột phải vào prefab trong bảng Project → Create▸Prefab Variant, rồi mở variant lên và sửa đúng những chỗ làm nó khác đi.

  • Một prefab cũng có thể nằm bên trong một prefab khác — cái bánh xe nằm trong chiếc xe — và mỗi cái vẫn giữ liên kết riêng. Unity gọi đó là nested prefab, và nó hoạt động y hệt bản bên ngoài.

Sinh prefab bằng code

Spawner.cs — the field holds the file, never the copy in the scene
using UnityEngine;

public class Spawner : MonoBehaviour
{
    public GameObject enemyPrefab;   // kéo asset từ bảng Project vào đây

    void Start()
    {
        Instantiate(enemyPrefab, transform.position, Quaternion.identity);
    }
}

Kéo file từ bảng Project vào ô đó — đừng kéo bản đang đứng trong Hierarchy. Trỏ vào một object trong cảnh thì mọi thứ vẫn chạy, cho tới lúc object đó bị xoá hoặc bị tắt, và đó là lỗi đứng sau một nửa số spawner hỏng từ xưa tới nay. Instantiate có bài riêng.

Hai trạng thái nên nhận ra

  • Một object màu đỏ tên Missing Prefab nghĩa là file nó đang bám theo đã bị xoá, hoặc bị di chuyển từ bên ngoài Unity. Object trong cảnh chỉ còn là cái vỏ rỗng; hãy trả file về chỗ cũ, hoặc xoá luôn cái vỏ.

  • Prefab > Unpack là cắt liên kết một cách cố ý: bạn giữ lại các object, và chúng thôi bám theo file. Dùng được đúng một lần, cho một mảng cảnh trí không bao giờ tái sử dụng; còn lại thì thường là để rồi tiếc.

bài học làm ra thứ này

Prefab hình khối

Bài này là một công thức đứng riêng. Trong khoá học, cùng thứ đó được dựng như một phần của dự án xuyên suốt năm tab — Căn bản, bài 07.