Skip to content

预制件

image-20260730142906690

“预制件”和“预制体”基本是在说同一个东西:Unity 的 Prefab

更常见的说法是:

Prefab = 预制体 / 预制件
Prefab Asset = Project 面板里的模板
Prefab Instance = Hierarchy 场景里的实例

unity-prefab-concept

一句话理解

预制体就是“保存好的 GameObject 模板”。

比如你做了一个敌人:

c
Enemy
├─ Transform
├─ SpriteRenderer
├─ Rigidbody2D
├─ Collider2D
└─ EnemyController.cs

你不想每一关都重新搭一遍敌人,就把它拖到 Project 面板里,生成:

c
Enemy.prefab

以后你可以把 Enemy.prefab 拖进任何场景。

Prefab Asset 和 Prefab Instance

Project 面板里的:

c
Enemy.prefab

叫 Prefab 资源,也就是模板。

Hierarchy 场景里的:

c
Enemy
Enemy
Enemy

叫 Prefab 实例。

关系是:

c
Enemy.prefab 模板
   -> 场景里的 Enemy #1
   -> 场景里的 Enemy #2
   -> 场景里的 Enemy #3

模板改了,实例通常也会跟着变。

Override 覆盖

如果你只改场景里某一个敌人,比如:

c
Enemy #1 血量 = 100
Enemy #2 血量 = 200
Enemy #3 血量 = 300

这些单独修改就叫 Override,也就是“实例覆盖”。

你会在 Inspector 里看到:

c
Overrides
Apply
Revert

意思是:

Apply:把这个实例的改动写回 Prefab 模板
Revert:撤销这个实例的改动,恢复成模板状态

新手要小心 Apply,因为它会影响所有使用这个 Prefab 的实例。

什么时候用 Prefab

凡是“会重复出现”的东西,都适合做成 Prefab:

c
玩家 Player
敌人 Enemy
子弹 Bullet
金币 Coin
血条 HealthBar
伤害数字 DamageText
按钮 Button
弹窗 Panel
特效 Explosion
道具 Item

比如发射子弹时,不可能提前在场景里摆好一百颗子弹,而是运行时生成:

c
using UnityEngine;

public class Shooter : MonoBehaviour
{
    public GameObject bulletPrefab;
    public Transform firePoint;

    public void Fire()
    {
        Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
    }
}

这里的:

c
bulletPrefab

就是你在 Inspector 里拖进去的 Bullet.prefab

销毁生成出来的 Prefab

Destroy(gameObject);

比如子弹飞出屏幕后销毁自己:

c
using UnityEngine;

public class Bullet : MonoBehaviour
{
    private void Start()
    {
        Destroy(gameObject, 3f);
    }
}

意思是:3 秒后销毁这颗子弹。

Prefab Variant 变体

Prefab Variant 是“基于某个 Prefab 的变种”。

比如:

c
Enemy.prefab
   -> FastEnemy.prefab
   -> TankEnemy.prefab
   -> BossEnemy.prefab

它们都继承 Enemy 的基础结构,但可以改不同属性:

c
FastEnemy:速度快,血少
TankEnemy:速度慢,血厚
BossEnemy:血很多,有特殊技能

这比复制一堆完全独立的 Prefab 更好维护。

Nested Prefab 嵌套预制体

Prefab 里面还可以放 Prefab。

比如:

c
Car.prefab
├─ Body
├─ Wheel.prefab
├─ Wheel.prefab
├─ Wheel.prefab
└─ Wheel.prefab

这叫嵌套 Prefab。

好处是:如果你改了 Wheel.prefab,所有车上的轮子都可以更新。

Unpack 是什么

当你右键一个 Prefab 实例,可能看到:

c
Unpack Prefab
Unpack Prefab Completely

意思是断开它和模板的关系。

断开后,它就变成普通 GameObject,不再跟随 Prefab 更新。

新手建议:别随手 Unpack。除非你明确知道这个物体以后不需要跟模板保持关系。

你现在最该记住的口诀

c
Project 里的是模板。
Hierarchy 里的是实例。
改实例叫 Override。
Apply 会写回模板。
Revert 会撤销实例修改。
重复出现的东西,就做成 Prefab。

把场景和 Prefab 放在一起理解:

c
Scene:装一堆对象的舞台
GameObject:舞台上的演员/道具
Component:演员身上的能力
Prefab:可以反复摆放的演员模板

这就是 Unity 项目能做大的关键机制之一。

使用Prefab的好处

unity-prefab-benefits

1. 避免重复劳动

比如你有一个敌人:

c
Enemy
├─ SpriteRenderer
├─ Animator
├─ Rigidbody2D
├─ Collider2D
└─ EnemyController.cs

如果不用 Prefab,每一关都要重新创建、挂组件、调参数,很麻烦。

做成:

c
Enemy.prefab

以后直接拖进场景就行。

2. 统一修改

这是 Prefab 最大的价值。

假设你在 10 个场景里都放了敌人。后来发现敌人的碰撞盒太大。

不用 Prefab:

c
你要去 10 个场景里一个个改

用 Prefab:

c
改 Enemy.prefab
所有关联实例都可以同步更新

项目越大,这个好处越明显。

3. 方便运行时生成对象

很多对象不是提前摆在场景里的,而是游戏运行时生成的:

c
子弹
敌人
金币
爆炸特效
伤害数字
掉落物
弹窗

例如生成子弹:

c
using UnityEngine;

public class Shooter : MonoBehaviour
{
    public GameObject bulletPrefab;
    public Transform firePoint;

    public void Fire()
    {
        Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
    }
}

这里的 bulletPrefab 就是一个 Prefab。

4. 保持项目结构清晰

Prefab 可以让你的资源更有条理:

c
Assets/
├─ Prefabs/
│  ├─ Player.prefab
│  ├─ Enemy.prefab
│  ├─ Bullet.prefab
│  ├─ Coin.prefab
│  └─ UI/
│     ├─ HealthBar.prefab
│     └─ Dialog.prefab

以后你想找玩家、敌人、UI、特效,都不会乱。

5. 支持变体

比如基础敌人是:

c
Enemy.prefab

你可以做出:

c
FastEnemy.prefab
TankEnemy.prefab
BossEnemy.prefab

它们共享基础结构,但有不同参数。

c
FastEnemy:速度快,血少
TankEnemy:速度慢,血厚
BossEnemy:血多,伤害高

这叫 Prefab Variant,很适合做同类对象的不同版本。

一句话记忆

c
重复出现的对象,用 Prefab。
需要统一修改的对象,用 Prefab。
运行时要生成的对象,用 Prefab。
同类对象有不同版本,用 Prefab Variant。

最典型的 Prefab:PlayerEnemyBulletCoinExplosionHealthBarPopup

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0