跳转到内容

理解章 B:为什么一切都是空壳加零件

约 3 分钟 难度:新手 理解章

第二部到此为止:GameObject、Component、Prefab、Material、Light。看着像五个零散的概念,其实它们在讲同一件事:Unity 把复杂东西拆成小零件,再让创作者自己组合。

这是这套工具能撑起大型项目的原因。

Hierarchy 里的名字只是标签:FloorGlowBallDoor 并不决定它能做什么。

名字只是给人看的。Unity 真正在乎的是这个 GameObject 身上挂了什么组件。

Floor 之所以像地板,是因为它有扁平的 Transform、有 Mesh Renderer 能被看见、有 Box Collider 能被踩住。把 Mesh Renderer 关掉,它还可以当隐形地板;把 Collider 删掉,它就只剩一块看得见、踩不住的板。

更准确的说法是:

GameObject = 一个带名字和 Transform 的容器
Component = 这个容器获得的具体能力

想象 Unity 里有专门的 Door 类型、Chair 类型、Lamp 类型、Button 类型。听起来挺贴心。

问题很快来了。一把会发光的椅子算椅子还是灯?一扇会播音效、能被脚本控制、还能同步给所有玩家的门,要继承几个类型?一个长得像石头、踩上去会开门的机关,是石头、按钮,还是机关?

每种东西都写死成一个类型,世界稍微复杂一点,类型树就会乱成一团。

Unity 选了另一条路:先给一个空壳,然后把能力拆成组件。要看得见就加 Mesh Renderer,要挡住玩家就加 Collider,要发光就加 Light,要播声音就加 Audio Source,要让玩家拿起来就加 VRC Pickup,要写自己的逻辑就加 Udon Behaviour。

一个物体的身份,来自它装上的能力。

Prefab 也可以放进这套思路里看。

配好一个 GlowBall:球体 Mesh、材质、Point Light、Collider、名字、Transform 层级,它已经是一组零件的组合结果。

Prefab 做的事就是把这组组合保存下来。以后需要第二个、第三个发光球,不用重新装一遍组件,从 Prefab 拖出来就行。修改 Prefab,相当于修改这套组合的源头。场景里的实例如果没有单独 Override,就一起更新。

Prefab 是 Unity 管理重复组合的方式。它比复制粘贴多了一层:修改源头时,所有实例跟着更新。

Material 看起来像美术资源,Light 看起来像场景灯具,但它们也遵循同一套拆分原则。

一个 Cube 的形状由 Mesh 决定,表面由 Material 决定,是否发光由 Light 组件决定,是否能被踩由 Collider 决定。每个部分只管自己那一摊。

这让排查问题精确起来:看得见但踩不住,查 Collider;踩得住但看不见,查 Mesh Renderer;球本身亮但照不亮墙,查 Light;材质颜色不对,查 Material 和 Shader;复制了很多份想统一改,查 Prefab。

拆开看,问题会小很多。

如果发现「照着步骤做了,物体还是不动」,可以按组件逐项查:

  1. 这个物体在哪?看 Transform。
  2. 它该不该被看见?看 Mesh Renderer 和 Material。
  3. 它该不该被碰到、点到、踩到?看 Collider。
  4. 它该不该发光或发声?看 Light 和 Audio Source。
  5. 它该不该响应玩家?看 Udon Behaviour、VRC Pickup、VRC Station 这类。
  6. 它是不是从 Prefab 来的?看有没有蓝色实例和 Override。

多数 bug 都有明确原因:某个能力没装、装错地方、参数没填,或者引用槽还是 None

第二部真正想留下的是这张图,按钮位置只是临时记忆:

Scene
└─ GameObject(空壳 + Transform)
├─ Component(能力)
├─ Material(表面外观)
├─ Light / Audio / Collider / Udon Behaviour ...
└─ Prefab(把一组配置保存成可复用模具)

看一个世界时,从外观往里拆。做一个世界时,从意图往外装。

「我想要一盏能被按钮开关的灯」这句话,现在可以翻译成具体清单:一个灯具模型、一个 Light 组件、一个按钮 Collider、一个 Udon 脚本、一个引用槽,把按钮和灯连起来。

这就是从玩家视角跨到创作者视角的第一步。