关于 scenario-unreal-vfx
面向 Unreal Niagara 特效与 Chaos 破坏制作的技能,指导从参数模板、材质和数据流配方到效果时序、可读性与性能评估。它通过画面评分和分线程测量检查效果。
主要功能
- 01按玩法参数规划特效时序
- 02使用模板和 User 参数契约
- 03配置 Niagara 效果类型与可扩展性
- 04制作 Chaos 破坏配方并检查物理设置
- 05评审捕获画面并测量线程性能
适用场景
- 01制作与伤害范围和命中时机一致的效果
- 02为大量特效配置池化与预算策略
- 03搭建可调参数的 Chaos 可破坏资产
- 04在目标硬件上评估特效视觉效果与性能
MCP 相关
README 未说明该技能与 MCP 的关系。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-unreal-vfx安装后在 Claude Code 中输入/scenario-unreal-vfx确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/ue_vfx.py详细介绍
Unreal VFX(Niagara、Chaos 破坏、VFX 评审)
专家级效果应当如实告知玩家(哪里会受到伤害、何时结束),在整个世界范围内的开销都符合其游戏玩法类别允许的标准,并通过目标核心数下的逐线程数据以及依据书面评分标准打分的捕获结果来验证。Python 无法创建 Niagara 发射器或模块(5.8 API):Agent 通过带有 User 参数契约的模板、Material Instances、Effect Types 和 Dataflow 配方来完成工作,并将少数图表编辑升级为精确的 GUI 请求。如果此处提到的同级技能不在可用技能中,请要求用户安装(npx skills add scenario-labs/skills --skill <name>);若无人值守,则根据工具架构继续操作,并标明这一缺口。
必备背景: scenario-unreal-expert(通道、评审循环、5.8 陷阱)。
状态(2026-09-24): 未安装 Unreal。离线检查通过
(python3 tests/code/unreal-vfx/run_all.py --offline);所有编辑器内代码片段尚未在 Unreal 中运行;job_00_vfx_probe.py 会给出 [verify] 名称。
立场(专家要点)
- 首先保证符合玩法事实。 最醒目的边缘应位于碰撞边界(导弹头、AoE 边缘),
并读取玩法数值(
User.Radius= 伤害半径),绝不能使用手工匹配的常量; 残留效果要传达出“仍然危险”的感觉(Keyser #1 [00:09:44]、[00:15:21])。 - 对比度是屏幕预算。 核心接近白色,但绝不纯白;饱和度集中在外围;晕光暗且饱和; 头部对比度最高;较弱的投射物应使用更亮的核心和暗色飘丝,而不是更亮的尾迹(Keyser #3 [00:08:13]、[00:12:03];#4 [00:19:55])。意外出现白色通常是叠加了多个加法混合效果:调整颜色前先统计生成数量,然后在加法混合的核心下方添加一层 Alpha 混合的饱和色层(Shishido [00:17:42]-[00:18:14])。
- 时序就是故事。 预备动作融入角色施法动画中(没有时间窗口时,就把重点放在衰减效果上);命中时恰好停止生成;闪光在命中帧达到峰值(“强度不等于尺寸”);后果紧随原因出现(先闪光,再是碎屑和火花,最后是烟雾);消散时间应短于蓄势时间,并在玩法窗口内结束。快速移动的圆形头部会产生频闪:沿速度方向拉伸,并将动态模糊烘焙到纹理中(Keyser #5 [00:08:13]-[00:09:54]、[00:14:34]、[00:18:07];#2 [00:03:31];Shishido [00:30:00]、[00:37:02])。
- 优化整个世界,而不是特效。 首先为每个系统设置一个 Effect Type:Lyra 的活动系统从 227 个降至 103 个,RT 从 5.07 ms 降至 1.51 ms,外观不变(Kiraly [00:20:48])。Effect Type 按系统设置,绝不按发射器设置;次级发射器使用 Scalability Mode Self。分别在目标核心数下查看 GT、GT Concurrent 和 RT [00:05:15],然后选择能节省对应线程的手段:距离剔除会停止更新,但不会停止渲染,而且可扩展性管理器也要为检查付出开销;剔除代理可以节省更新开销,但不能节省 RT [00:16:57]、[00:18:02];每个 GPU 系统都会产生 RT 分派开销,即使不可见也一样 [00:05:47]。仅对非关键类型启用 FX 预算,并使用
fx.Budget.AdjustedUsageDecayRate来应对振荡 [00:36:50]-[00:37:21]。 - 按类别和频率设计生成架构(Kiraly 的表格 [00:45:57]):对频率适中的单次效果使用对象池(Manual Release 表示 Release to Pool);对高频生成使用 Data Channel 侦听器;对简单爆发效果使用关闭系统状态的无状态发射器(脚步声的 GT 从 1,387 降至 271 us [00:39:24]);NDC 和无状态模式互斥;数量较少时使用 CPU。
- 破坏效果的开销取决于活动刚体和接触。 按以下顺序处理:渲染(GC 上启用 Nanite,使用 ISM renderer 的根代理);刚体数量和生命周期(群集、启用 Remove on Break 并设置随机计时器和 Cluster Crumbling、按平台设置移除倍率、Tiny Geo);碰撞(碎屑使用单向碰撞,每个群集使用一个凸包,盒体尺寸低于相对尺寸的 0.3);最后再调节流量限制(Caillaud wPgd1J1Tf70 [00:03:47]-[00:16:18];Xiao Yue zFiHDRREv7E [00:29:27])。
- 武器应通过应变而不是场来破坏墙壁。 应用 External Strain,并应用按投射物速度缩放的 Apply Breaking Linear Velocity,不使用应变衰减;场“又重又慢”(Van Allen [00:29:29])。选择一种伤害模型:Material Strength and Connectivity(在物理材质上调整抗拉强度)或按关卡设置阈值(调整数组);按尺寸区分只是一个标志,不是一种模型(Xiao Yue [00:19:54]-[00:20:27])。重量感来自摩擦力(合并模式设为 Max)和较低的恢复系数;石材密度为 2 g/cm3,2000 是单位错误(Van Allen [00:26:11])。
- 用配方,而非点击操作。 带有公开参数的模板,以及包含每个资产变量的 Dataflow 图,都能适应美术改动,也是 Agent 可以可靠使用的内容(Caillaud t_jyTILDYo8 [00:02:46])。
首先确定
| 输入 | 为什么会影响计划 | 未提供时的默认值 |
|---|---|---|
| 平台、帧率、最低配置核心数 | 每线程预算、质量表 | PC 60 fps;核心数采用 scenario-unreal-performance 中的数值,若未知则按 4 个处理(Kiraly) |
| 游戏玩法数值(scenario-unreal-gameplay) | 半径、速度、伤害窗口、射速、同时存在的最大数量、施法动画时长 | 询问;绝不猜测半径 |
| 摄像机和环境 | 在实际地面颜色背景下,从游戏距离观察 | 游戏的摄像机和关卡 |
| 风格支柱、重要性等级 | 亮度预算:待机、基础、防御、造成伤害、改变战局、终极(Keyser #1 [00:13:08]) | 由美术负责人提供的三个支柱 |
| 人群和破坏范围 | 屏幕上的副本数量;每个关卡中的墙体数量、必须破坏的物体、低端平台 | 最坏但合理的战斗场景;实时运行,启用 Nanite |
| 预算 | 没有来源给出每种效果的毫秒预算 | [added] 在最低配置下,所有 Niagara 的 GT + GT Concurrent 耗时约为 2 ms 或更低,RT 耗时为 1.5 ms;与 scenario-unreal-performance 确认 |
工作流
-
每个引擎探测一次。
job_00_vfx_probe.py(无头模式)。GATE:probe.json回答[verify]项。 -
对元素进行分类,并将它们分组成系统。 对每个元素执行
classify_element,然后执行system_plan:每个系统使用一个 Effect Type(取其最关键的元素);其余元素设为 Scalability Mode Self,或者在容易刷屏或使用 GPU 时为其单独创建系统。系统(示例) Effect Type 关键发射器 次要发射器(Scalability Mode Self) 投射物、光束、曳光弹 NET_OneShotCritical 弹头 拖尾、游丝、余烬 撞击、命中、枪口火焰 NET_OneShotCritical 闪光、伤害环 烟雾、火花(容易刷屏或使用 GPU 时拆分) 碎片或撞击侦听器(NDC) NET_OneShot,仅在衰减阻尼时计入预算 无 全部 AoE、状态效果、拾取物 NET_PersistentCritical 边缘 内部装饰效果 环境灰尘、树叶、雨水 NET_Ambient 无 全部 GATE:
system_plan无错误。 -
构建前制定时序计划。 编写生成时序表(从施放动画的预备动作开始,到命中时结束的蓄力过程、命中时的闪光、碎片和火花、烟雾、窗口结束),并运行
spawn_schedule_verdict;strobe_risk(speed, head length)会给出快速头部所需的拉伸幅度。门槛:无错误;拉伸幅度符合模板规范。 -
模板和契约。 使用
duplicate_template、user_parameters、contract_verdict;缺少的控件会转化为一项 GUI 请求。该请求中的曲线需通过fade_curve_verdict(不透明度从生命周期中段开始淡出,不能只缩小)和flipbook_playback_verdict(先快后慢)。门槛:契约通过。 -
外观:材质和纹理。 使用 scenario-unreal-materials 中的主材质和实例(侵蚀、渐变映射 LUT、深度淡化);优先复用纹理(Trümpler [00:16:33]),用 Python 生成辉光、LUT 和噪声。导入蒙版时关闭 sRGB,使用
TEXTUREGROUP_Effects,大型源纹理通过 Maximum Texture Size 限制尺寸。烘焙的翻页书纹理经过预乘,因此材质必须将 RGB 除以 A(premultiplied_check)。烟雾和火焰:默认使用烘焙翻页书纹理;Fluids 处于 Beta 阶段。门槛:audit_vfx_textures、flipbook_check均无问题。 -
系统属性和可扩展性。 使用
set_system_properties设置:effect_type、max_pool_size= 该类型的系统上限、中途加载时 prime 为 0、warmup 为 0、静态效果关闭当前帧数据;世界空间拖尾需要设置固定边界,大小为速度 × 生命周期(fixed_bounds_check)。使用EFFECT_TYPE_PRESETS中的 Effect Types(通过create_effect_type[verify] 创建,或只在 GUI 中创建一次)。门槛:audit_niagara中无NO_EFFECT_TYPE;caps_verdict、budget_verdict均无问题。 -
接入游戏玩法。 scenario-unreal-gameplay 使用对象池方法生成效果,根据游戏玩法数据设置 User 参数,从施放动画生成预备动作,写入 Data Channel 负载,并在命中时施加应变(
strain_plan;必须破坏的物体需同时使用碰撞和应变)。命中时,停用拖尾并让其粒子自然结束 [added]。门槛:PIE 中的命中效果从对象池生成(FX Outliner 显示 InUse / FreeInPool)。 -
可破坏资产。 源网格需水密、无相交(
mesh_watertight_check);使用固定种子;按材质设计图案(混凝土噪声和灰浆、木材收缩-断裂-拉伸、玻璃切片或裂纹材质);设置两到三个层级并锚定;使用带面积阈值的 Proximity 图;一种损伤模型;每个簇使用一个凸包;使用带表面距离烘焙的内部材质(Caillaud t_jy [00:29:14]);设置 Remove on Break 范围和 Cluster Crumbling;在低端设备配置文件中设置移除倍率;禁用不会被唤醒的静止碎片(Xiao Yue [00:28:45])。破坏效果需要在 Project Settings 中生成 Chaos 数据,并在组件上启用破坏通知(enable_break_events,Xiao Yue [00:08:42]);仅将已破坏的骨骼切换为碎片配置文件。然后运行harden_gc;在测试场景中测试碎片数量为 10、50、100 的情况(Caillaud t_jy [00:35:12])。门槛:gc_recipe_verdict、gc_verdict、physmat_check均无问题。 -
评审循环。 使用带纹理的评审关卡、Manual exposure 和游戏玩法摄像机;使用
live_capture_series.py或capture_ages配合干净底板;运行score_captures.py(空白帧会使整个系列无效);查看颜色、灰度和眯眼检查表;在 PIE 中重复检查(“视口会骗人”,Shishido [00:05:05]),在绿色和棕色地面上检查色盲适应性,在人群网格中检查,并测试sg.EffectsQuality0 到 3。出现过曝时,先对 Debugger 计数运行duplicate_spawn_check。每轮只改一项。门槛:无评分标准不合格项;已对各评判项打分(references/critique.md)。 -
测量。 在目标核心数下,固定测试最坏情况战斗:
stat unit、stat NiagaraOverview、Debug HUD、使用-statnamedevents的 Insights(没有该参数时 Niagara 不可见,Kiraly [00:10:52]);运行init_for_performance_baseline();每次更改前运行lever_check;启用预算时运行budget_oscillation。破坏效果:在破坏前后采集帧序列、CVD、t.OverrideFPS 60[verify]。门槛:niagara_overview_verdict、before_after、destruction_run_verdict均在预算内,视觉效果一致。 -
交付预算表给 scenario-unreal-performance。
数值
| 数值 | 相对于 | 来源 |
|---|---|---|
| NET_OneShot:每个系统 15 个,每种类型约 30 个,仅生成时触发,销毁并清除,即时剔除 0.0 | 即发即弃,不重要 | Kiraly [00:22:26] |
| NET_PickupPersistent:5 个(视线范围),持续运行,休眠,剔除延迟 1.0 s | 持续且重要 | Kiraly [00:24:03] |
| 最大池大小 32,初始值 0(默认值);类型上限 = 池大小 | 每个系统 | Kiraly [00:32:18], [00:33:22] |
| 1024 上的 Flipbook 为 8 x 8,即每个图块 128 px,结束帧 63,以 30 fps 烘焙 | 烘焙器 | Flipbook Baker 文档 |
| 阈值 5000 / 500 / 50;应变 50000,半径 100,速度 500 | 快速入门墙体 | Chaos 文档 |
| 碰撞箱小于相对尺寸的 0.3;4 个层级中有 4,000 个碎片,约 200 个刚体被击中 | 叶片代理;聚类 | Xiao Yue [00:25:51], [00:22:32] |
| 休眠 3 s 后移除;5 到 10 s 后移除,然后应用平台乘数 | 碎片 | Caillaud [00:10:43], [00:11:24] |
质量门槛
- **可测量:**审计(
audit_niagara、audit_gc、audit_vfx_textures、caps_verdict、system_plan、gc_recipe_verdict);目标核心数下的每线程统计数据、平均值和峰值;破坏峰值与恢复情况;采集评估标准(占屏面积与半径、数值区间、溢出、数值下的饱和度、焦点处的重点色与 60 / 30 / 10 配色、随时间保持的尺寸类别、头部对比度、色盲对比度、强度曲线、调度、频闪);image_checks会拒绝空白帧。 - **视觉:**在游戏距离下检查灰度效果;避免爆闪;剧情节拍;人群识别效果;不同画质等级间不出现跳变;破坏效果应呈现材料质感、内部厚实,不出现悬浮碎块,碎片具有重量感,移除过程由尘土掩盖。
常见错误
| 错误 | 表现 | 修复 |
|---|---|---|
| 手动匹配半径 | 环形区域大于伤害区域 | 使用游戏玩法中的 User.Radius |
| 白色过曝 | 一团平白色 | 统计重复粒子,然后在加法核心后方添加一个经过 Alpha 混合的高饱和度图层 |
| 高速时头部呈圆形 | 闪烁的圆点 | 沿速度方向拉伸,并在纹理中添加运动模糊 |
| 命中后才开始聚集;烟雾早于闪光 | 效果显得混乱 | 设置生成顺序:命中时停止,先生成成因效果 |
| 仅通过缩小淡出 | 卡片效果闪烁 | 从生命周期中段开始淡化不透明度,并匹配图层颜色 |
| 每个发射器都设置 Effect Type | 余烬获得不可剔除的类型 | 每个系统只用一种类型,并将 Scalability Mode 设为 Self |
| 通过距离剔除来减少 RT | RT 没有变化 | lever_check:限制数量、CPU 模拟、无状态 |
| 预算没有衰减 | 剔除、重新生成、再剔除 | 设置衰减率,仅用于非关键类型 |
| 固定边界小于拖尾 | 拖尾在屏幕上消失 | fixed_bounds_check |
| 撞击时销毁投射物 | 拖尾突然消失 | 停用投射物,让粒子自然结束 |
| 通过睡眠固定在墙面 | 受到碰撞后醒来 | 使用锚点或运动学骨骼 |
| 默认连接图 | 碎块悬浮、角部铰链 | 使用 Proximity 或 Bounds Overlap Filtered |
| MSC 使用经过调整的阈值数组 | 调整参数不起作用 | 设置物理材质上的拉伸强度 |
| 每发子弹都设置场或应变衰减 | 物理计算出现峰值 | 使用应变和断裂速度,不设置衰减 |
| 整个 GC 使用碎片配置 | 玩家可以穿过完整墙体 | 在断裂事件中切换断裂骨骼 |
| 休眠的碎片永不唤醒 | 求解器开销 | 禁用 |
gc.removal_duration = ... | 被拒绝(只读属性) | 使用 set_editor_property |
交接
- 接收来自 scenario-unreal-materials:粒子主材质、实例、纹理设置;来自 scenario-unreal-gameplay:数值、施法动画时序、池化生成、NDC 写入、应变调用;来自 scenario-unreal-world-building:可破坏物的放置与数量。
- 交付给 scenario-unreal-performance:预算表(系统、Effect Type、上限、池、模拟目标、每线程成本、核心数、质量;GC 的碎片数量、活动刚体峰值、破碎峰值、恢复情况),以及可重复的场景;给 scenario-unreal-cinematics:Chaos 缓存、电影级可伸缩性;给 scenario-unreal-lighting-rendering:粒子光源、异构体积。布料归 scenario-unreal-animation。
UE 5.8 说明
- Data Channels 自 5.5 起已可用于生产环境(GDC 2025 演讲仍称其为实验性功能);轻量级发射器自 5.5 起为 Beta,5.7 起移除了编译步骤;Niagara Fluids 为 Beta;“Empty”模板即“Minimal”。
r.HeterogeneousVolumes.Allow(5.8);Niagara Editor Preview Actor(5.7)。- Chaos:创建 GC 时默认使用 Dataflow 模板,支持运行时 Dataflow 求值(5.8);项目设置中提供破坏节流选项(5.6)。
- GC Python:
root_proxy_data、size_specific_data、set_dataflow_asset;每骨骼数据(锚点、断裂时移除、单向级别)不属于该类。
参考资料
references/expert-notes.md:专家提出的原则、时间戳、不同意见,以及 U7 评分发现的缺失项。references/procedures.md:每个流程的完整代码、测试路径和状态。references/critique.md:评估标准(指标、阈值、判断项)。references/gui-paths.md:完成相同工作的编辑器菜单。references/sources.md:所有来源、凭据、URL、最佳时间戳、修订历史。scripts/ue_vfx.py:离线评估结果和指标;编辑器内辅助工具(尚未运行)。