资产生成的组件:网格、声音、粒子怎么变成 component
正课里你自己写了一个 component。但等一下——mesh_component 你可没写过,它是从哪冒出来的?答案是 UEFN 替你写的:项目里已有的网格、声音、粒子资产,会自动生成对应的组件类。这叫 asset-generated component,它是 Scene Graph 里数量最多的一类组件。
一、来历:资产自己长出组件类
官方给的定义很短:asset-generated component 是根据项目里已有的内容(网格、声音、粒子系统等资产)自动创建的组件类。这些资产还可能顺带暴露一些属性,让你在生成出来的组件上直接改。
关键的一步在于:导入或创建资产之后,你需要编译一次项目的 Verse 代码,组件类才会被生成出来。这条容易被忽略——刚导入一个 .fbx 却在 Add Component 列表里找不到它,十有八九就是还没编译。
这套机制解释了一个新手常有的困惑:「Scene Graph 里到底有多少种 component?」内置的那几十种(变换、灯光、碰撞、相机、可交互……)只是骨架,真正撑起一个项目的是你自己的资产生成出来的那一大批。项目里有多少可用资产,列表就有多长。
顺带把上一课的一句话补完整:entity 是容器,component 是能力。而在这套设计里,「长成什么样」也是一种能力——它不是 entity 的固有属性,而是由某个资产生成的组件带进来的。一个 entity 没有 mesh_component,就是彻底看不见的:它照样存在、照样可以有逻辑,只是没有身体。
二、mesh_component:最典型的一个
网格组件在 Verse 里的类名就叫 mesh_component。它给 entity 加上「看得见的形体」,是最常被装上的组件,没有之一。官方文档列出的可调选项如下:
| 选项 | 取值 | 作用 |
|---|---|---|
| Enable | True / False | 启用或停用这个组件 |
| Collidable | True / False | 是否参与物理碰撞 |
| Queryable | True / False | 是否可以被 Verse 代码引用 |
| Visible | True / False | 在场景里是否显示 |
材质槽也在这里:从网格的下拉菜单里可以选中并覆盖材质。官方还有一句措辞值得留意——资产生成的组件总是从组件下拉菜单里覆盖,也就是说你不是在改资产本身,而是在这个 entity 上给它一个覆盖值。这和蓝图里「改 Static Mesh Component 的 Material Override 而不动母材质」是一个道理。
代码里怎么用?第 27 课的对照表里已经出现过了:Entity.GetComponent[mesh_component] 拿到它,然后调用它的 Enable() / Disable() 就能开关显示。Epic 官方教程里那个「循环消失的平台」正是这么做的:
blink_component<public> := class<final_super>(component):
@editable
Duration<public>:float = 2.0
# 藏起来:把这个 entity 上的网格组件关掉
Hide():void =
if (Mesh := Entity.GetComponent[mesh_component]):
Mesh.Disable()
# 露出来:再开回去
Show():void =
if (Mesh := Entity.GetComponent[mesh_component]):
Mesh.Enable()
OnSimulate<override>()<suspends>:void =
loop:
Sleep(Duration)
Hide()
Sleep(Duration)
Show()
读图翻译:这个组件本身不知道自己被装在什么东西上,它只是问一句「你身上有网格吗」,有就开关它。同一个 blink_component 装到方块上、装到台阶上、装到一棵树上,都能工作——因为它依赖的是能力而不是类型。这句话可以当成整个 Scene Graph 的口号。
注意 GetComponent 外面那圈 if:查找是可能失败的操作,必须放进失败上下文。这是 Verse 从语法层面消灭 Accessed None 的老办法(第 12、18 课讲过),放到组件查找上依然成立。
三、三条要提前知道的限制
- ▢ 一个 entity 上,同类组件只能有一个。官方原话:同一个组件类或其子类只能添加一个。所以一个 entity 上不能挂两个网格。想拼一个由三块网格组成的物体?正确做法是建三个子 entity,各挂一块。这是与蓝图差异最大的一条——蓝图里一个 Actor 挂五个 Static Mesh Component 是家常便饭。
- ▢ 导入资产后要编译才会生成组件类。见第一节。找不到新资产就先编译一次。
- ▢ 不是所有资产都能用。官方明确写道:Fortnite 自带的静态网格与 FAB 资产目前不兼容 UEFN 里的 Scene Graph;可直接作为 mesh_component 使用的静态网格是那些基础形状。要用自定义网格,得自己导入 .fbx 之类的 3D 网格文件,或者用 UEFN 的建模工具现做一个。
第三条会实打实影响你的开工节奏:如果你的既有工作流是「从 FAB 拉资产、拖进关卡」,搬到 Scene Graph 上时得先解决资产来源问题。这也提醒我们一件事——Scene Graph 在 UEFN 里仍在推进中,能力边界会随版本移动,做计划前先看当时的官方说明。
四、与「拖一个 Static Mesh Component 进来」的对照
蓝图作者对这套流程闭着眼都能走:打开 Actor 蓝图 → Components 面板 +Add → Static Mesh Component → 在 Details 里的 Static Mesh 那一栏选资产 → 顺手改材质、勾碰撞。Scene Graph 的动作几乎逐格对应:
| 蓝图里的做法 | Scene Graph 里的做法 | 差异 |
|---|---|---|
| Components 面板加一个 Static Mesh Component | Details 面板 Add Component,挑网格组件 | 动作一致;Scene Graph 限定一个 entity 只能有一个 |
| 在 Details 的 Static Mesh 一栏选资产 | 组件下拉菜单里选网格(资产生成的组件从这里覆盖) | 资产要先导入并编译过 Verse,才会出现在列表里 |
| Material Override 覆盖材质 | 材质槽从网格下拉菜单里选中并覆盖 | 语义相同:改的是这个实例,不动母资产 |
| Collision Presets 调碰撞 | Collidable 开关 | Scene Graph 目前的粒度更粗,以官方文档为准 |
| Set Visibility 节点 | Mesh.Enable() / Mesh.Disable() |
要先用 GetComponent[mesh_component] 拿到组件,而那是可能失败的表达式 |
| 一个 Actor 挂五个 Static Mesh Component | 五个子 entity,各挂一个网格组件 | 差异最大的一条:层级从「组件列表」变成了「entity 树」 |
最后一行值得多说一句。蓝图里「一个 Actor + 一串组件」是扁平的,组件之间靠 Attach Parent 建立层级;Scene Graph 里层级天然由 entity 承担,组件反而变成了每个 entity 身上的一张薄薄的能力清单。结果是:你的场景结构会比蓝图更瘦、更深——entity 更多,每个 entity 上的组件更少。第一次搭复杂物体时会觉得啰嗦,习惯之后会发现每一层的职责都干净得多。
你想做一辆车:一个车身网格 + 四个车轮网格。在 Scene Graph 里应该怎么搭?
来源
本文整理自 Epic 官方文档:
- Mesh Component in Unreal Editor for Fortnite(官方文档)↗
- Getting Started in Scene Graph in Fortnite(官方文档)↗
- Verse API:/Verse.org/SceneGraph 模块(官方 API 参考)↗
Scene Graph 在 UEFN 中仍在演进,可用资产范围与组件属性会随版本变化,以当时的官方文档为准。