mcpField
S
scenario-unreal-gameplay

scenario-unreal-gameplay

github.com/scenario-labs开发1.2k199 次安装1 天前更新
代码仓库

关于 scenario-unreal-gameplay

面向 Unreal Engine 游戏玩法开发的专业技能,指导 Agent 规划数据归属、C++ 与 Blueprint 分工、GAS、AI、输入和 UI,并通过隔离测试与质量门检查实现。

主要功能

  1. 01按生命周期与网络状态放置数据
  2. 02规划 C++ 与 Blueprint 职责
  3. 03配置 GAS、输入与 AI 工作流
  4. 04检查 StateTree、UI 和游戏逻辑
  5. 05通过调试与自动化测试验证机制

适用场景

  1. 01规划多人游戏中的复制状态与 ASC 初始化
  2. 02搭建角色能力、输入映射和 AI 状态树
  3. 03验证跳跃、冲刺、冷却与生命值 UI
  4. 04检查性能指标并评审游戏玩法实现

MCP 相关

README 将 Epic 的 MCP 工具集列为处理 Blueprint 图内容的途径之一;未说明该技能自身提供 MCP 服务。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/scenario-labs/skills --skill scenario-unreal-gameplay

安装后在 Claude Code 中输入/scenario-unreal-gameplay确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
critique.md
expert-notes.md
gui-paths.md
procedures.md
sources.md
scripts/
ue_gameplay_cpp.py
ue_gameplay.py

详细介绍

虚幻游戏玩法(框架、Blueprint 与 C++、输入、GAS、AI、UI)

专家级实践意味着,每项数据都存放在其生命周期和网络状态与之匹配的类中;逻辑以文本形式编写(C++ 或小型函数),位于仅存放数据的 Blueprint 和由 Python 配置的数据资产之下;每项机制都要先单独验证(注入输入、调试命令、追踪),再在游戏中评估。Agent 不会假装能创作自己无法操作的图表:它会说明每部分最终落在哪种载体上,并且只对剩余部分升级处理。如果此处提到的同级技能缺少某项,请用户安装它 (npx skills add scenario-labs/skills --skill <name>);如果用户未能及时处理,则根据工具架构继续,并标明这一缺口。

必备背景: scenario-unreal-expert(通道、审查循环、5.8 陷阱)。

状态(2026-09-24): 尚未安装 Unreal。离线层已通过 (python3 tests/code/unreal-gameplay/run_all.py --offline)。所有编辑器内代码片段和生成的 C++ 文件尚未在 Unreal 中运行(C++ 尚未编译);job_00_gameplay_probe.py 会给出 [verify] 名称。

核心立场(专家经验补充)

  • 根据数据生命周期和网络可见范围来放置数据。 GameMode 仅存在于服务器,负责规则;GameState 和 PlayerState 会复制给所有人;PlayerController 仅对所属客户端可见;Pawn 是可重生的身体;GameInstance 子系统的生命周期长于地图(Forsythe IaU2Hue-ApI [00:13:26])。状态放入带 RepNotify 的复制属性中,绝不使用 multicast;C++ RepNotify 不会在服务器上触发(JOJP0CvpB8w [00:10:50]、[00:14:48])。在 World Partition 下,BeginPlay 可能运行多次:务必保证其幂等(Shao KBn62trwkLw [00:07:29])。
  • 以 C++ 为基类,Blueprint 子类只存数据;Blueprint 可以依赖 C++,反之则不行(Forsythe VMZftEVDuCE [00:24:10])。调优项用 EditDefaultsOnly,资产选项用 TSubclassOf 插槽,外观效果用 BlueprintImplementableEvent 钩子:逻辑用便于比较差异的文本编写,Blueprint 作为默认值配置。广播者通过单向委托触发事件(OnDied),由控制器、生成器和 HUD 绑定([00:19:25])。
  • Blueprint 的开销按节点计算;真正的成本在于硬引用。 与 CharacterMovement 更新相比,Tick 开销微不足道;转换为 Blueprint 类会使其与转换者一同加载(Arnbjörnsson S2olUc9zcB8 [00:06:07]、[00:28:01])。只有当 Insights 跟踪显示某段代码位于热点集中时,才将其移至 C++(Forsythe [00:16:33])。
  • 效果说明是什么,能力说明何时发生。 新功能应使用新的响应式资产,通过标签监听;响应逻辑查询 GE 的资产标签;使用一个带 SetByCaller 的伤害 GE;使用 Wait Delay,而非 Delay;始终调用 End Ability;使用 PlayMontageAndWait;Gameplay Cues 仅用于外观效果(Shao 8bi0rnXnRj4 [00:19:25]、[00:47:35]、[00:21:43]、[00:49:12]、[00:13:02];tranek 9.3)。只有在代码设置后,SetByCaller 值才存在,因此控制台隔离测试要使用固定幅度的对应版本[新增]。
  • 在两端连接 ASC。 将 ASC 放在 Pawn 上,除非属性需要在重生后保留(此时放在 PlayerState 上);在服务器端的 PossessedBy 中,以及所属客户端的 PlayerController 的 AcknowledgePossession(或 OnRep_PlayerState)中调用 InitAbilityActorInfo;玩家使用 Mixed,AI 使用 Minimal,并尽早设置;绝不预测伤害(tranek 4.1、4.1.2、7.3、4.10)。
  • 输入是带间接层的数据。 输入 Action 映射到输入标签,再映射到能力,因此 Pawn 不包含任何能力逻辑(Noland,Lyra Fj1zCsYydD8 [00:34:33]);不同游戏状态的映射上下文应互斥(框架文档)。
  • StateTree 会在任何转换发生前选择一个叶节点,并且只在转换要求时重新检查进入条件(Mononen YEmq4kcblj4 [00:11:22])。每个应该结束状态的条件都需要事件或转换;每个状态都应明确设置成功和失败的退出方式,否则会回退到根节点([00:14:13]);通过绑定提供数据,将调优项设为树参数([00:16:40]);动作委托给 Gameplay Ability,并设置超时(Bruno XKQfMZOXFv0 [00:17:37]、[00:19:15])。
  • UI 通过事件更新,绝不使用属性绑定;开启 Global Invalidation,然后排查被冻结的控件(Albert VxX1aah6TZM [00:24:09])。控件 Tick 从 Paint 触发,文本更改会导致布局失效,Hidden 只会重绘,而 Collapsed 会重新布局([00:10:09]、[00:13:56]、[00:12:53])。

先明确

输入为何会改变计划未说明时的默认值
单人或多人、监听服务器或专用服务器ASC 放置、复制模式、预测、测试矩阵单人,从第一天起就进行权威性检查(网络文档)
C++ 工具链已安装 Xcode 26.6;Epic 列出的最低版本为 26.0,推荐 26.1.1,26.4 不兼容,未列出 26.6在承诺使用 C++ 前先探测构建(P3);否则采用 Blueprint 加数据的备用方案
规模数十个 Actor、数百个静态可交互对象,还是数千个移动对象Actor;然后是 Instanced Actors,再然后是 Mass(KBn62trwkLw [00:01:06])
手感目标跳跃高度、冲刺距离、冷却时间、行走和追逐速度询问;不调整 CharacterMovement 默认值会「感觉像 Unreal 教程项目」(IaU2Hue-ApI [00:23:39])
帧预算、平台Tick 和 AI 上限60 fps;数值参考 scenario-unreal-performance
角色和关卡输入骨架、蒙太奇、通知;导航边界、玩家起始点、流送参考 scenario-unreal-animation 和 scenario-unreal-world-building

创作方式

可脚本化:C++ 类、Blueprint 子类及其 CDO 默认值、数据资产和数据表、Enhanced Input 资产、Gameplay Effect 外壳、StateTree 资产和参数、控件树 (EditorUtilityLibrary.add_source_widget)。图表内容(事件图表、GE 修改器〔Python 无法实例化〕、StateTree 状态和转换、Behavior Tree 节点)应通过按变体复制的模板、Epic 的 MCP 工具集、调用 help() 后使用 5.8 BlueprintGraphEditor,或一次精准的 GUI 操作来完成。完整表格:流程 P15。

工作流

  1. 每个引擎探测一次。 job_00_gameplay_probe.py(无头模式)会列出技能标记为 [verify] 的类、属性和 cvar,包括 AbilitySystem.Fix... 资产标签 cvar,以及一个 dumpticks 示例。门槛:已写入 probe.json。
  2. 做出决策。 ue_gameplay.decide(spec):数据放置位置、使用 Blueprint 还是 C++、是否使用 GAS、AI 系统、ASC 放置位置、初始化和复制、通信、UI,以及各自的决策条件。门槛:每项数据都有所有者、复制方式和存续情况(重生、地图切换、流式加载)。
  3. 搭建项目和配置。 ue_env.enable_plugins;使用 ini_set 设置 bUseDebugTargetFromHud、将资产标签 cvar 设为 0、配置标签;为 showdebug 设置一个 GameMode HUD 类。门槛:config_verdict 无问题。
  4. C++ 层。 cpp_scaffold()(角色基类、玩家控制器、冲刺和近战能力、AI 控制器、StateTree 任务、生命值小组件、本机标签),patch_build_cs()、build_command();新增反射成员时关闭编辑器。门槛:构建退出码为 0;cpp_lint 无错误(包含 ASC_CLIENT_INIT_MISSING)。
  5. 通过 Python 构建数据层。 Blueprint 子类和 CDO 默认值:移动、JumpMaxCount = 2、GameMode 上的 player_controller_class,以及每个 AI pawn 上的 ai_controller_class = 持有树的控制器 Blueprint,并设置 auto_possess_ai 为 placed 或 spawned。通过 input_plan() 创建输入资产,通过 ge_plan_verdict 检查计划中的 GE 资产,以及 StateTree 资产和小组件树。门槛:ge_plan_verdict 和 audit_gameplay() 无问题。
  6. 清理图表残留。 将每棵树写为 spec,通过 statetree_spec_verdict 检查;通过 MCP 工具集或一次 GUI 操作从 statetree_outline 连接各节点(references/gui-paths.md);按敌人设置树参数。门槛:spec 检查通过;树编译时没有未绑定的 Inputs;ai_setup_verdict 无问题。
  7. 先单独测试,再测试整个链路。 在控制台使用固定数值的调试 GE,使用 showdebug abilitysystem(3 页),对每个 AI 使用游戏性调试器;通过 gas_log_triage 读取 log LogAbilitySystem VeryVerbose;然后使用 pie_scenario 或 PythonAutomationTest 注入 Input.+key,并由阈值根据参数推导出的分析器判定(analyze_jump、dash_expected_cm、analyze_cooldown、state_sequence_verdict、health_bar_verdict)。门槛:每个场景均通过,没有卡住的能力,也没有未计划的根状态进入。
  8. 收集证据并审查。 截取调试页面、showdebug enhancedinput、受伤前后的生命值条、各状态下的敌人和导航网格覆盖范围;查看前先运行 ue_review.image_checks。门槛:没有空白画面;UI 保持同步。
  9. 测量。 使用开发版本或在新窗口中运行 PIE:stat game、stat unit、dumpticks(tick_verdict)、在关闭和开启 Global Invalidation 时运行 stat slate,并在任何重写之前记录场景的 Insights 跟踪(rewrite_gate)。门槛:tick 清点有充分依据;仅重写热集函数;将跟踪交给 scenario-unreal-performance。

数值

数值相对于来源
每个 Actor 的 Tick 开销:BP 在编辑器中为 3.59 us,打包后为 1.84 us;C++ 约为 0.64 至 0.70 us100,000 个 Actor,UE 5.4Arnbjörnsson [00:05:00]
CMC 为 241 us,PlayerController 每帧为 125 us同一 Lyra 帧Arnbjörnsson [00:06:07]
BP 节点打包后为 0.1 us(编辑器中为 0.5);C++ 调用为 0.7 us(编辑器中为 0.8)每次调用Arnbjörnsson [00:18:48]
Print String 每次调用为 88.8 至 272.5 usDevelopment 构建Arnbjörnsson 演示文稿 00:20:10
Fortnite:客户端每帧约 80 次 Tick,服务器为 700 次Tick 函数Arnbjörnsson [00:11:03]
每帧处理几十个结果时,GetAllActorsOfClass 没问题;WithTag 和 WithInterface 会扫描每个 Actor世界规模Arnbjörnsson [00:37:17],[00:38:56]
空 Tick:从 5.6 起免费编译器会将其禁用myth article
最多 20 个活跃敌人;异步路径偏移为 0.2 至 0.5 s;攻击者为 1 个危险敌人或最多 3 个弱敌人Lords of the Fallen,主机平台,每位玩家Bruno [00:16:25],[00:15:20],[00:38:40]
Lyra 模态框弹出时重绘了 207 个 Widget;修复后为 25 个绘制次数Albert [00:35:03]
跳跃顶点高度 h = v^2 / 2g;二段跳会重置 Velocity.Z,按下时增加高度 hJumpZVelocity,重力 980 cm/s^2 x GravityScale物理 [新增]
地面冲刺 = 速度 x 持续时间 + 退出滑行距离(以 600 cm/s 计算约为 24 cm)GroundFriction 8,BrakingFrictionFactor 2,BrakingDecelerationWalking 2048引擎模型 [新增,待验证]

质量门槛

  • 可测量: cpp_lint(资源路径和依赖方向、多播状态、Tick 中的 Reliable RPC、服务器上的 OnRep、客户端 ASC 初始化、Widget Tick、Collapsed 切换、重复 BeginPlay); ge_plan_verdict;statetree_spec_verdict;ai_setup_verdict;audit_gameplay(Tick 清点、 硬引用闭包、冷却标签、Widget 绑定);带派生阈值的场景 verdict;gas_log_triage 为空; showdebug abilitysystem 未显示卡住的能力;StateTree 跟踪中没有计划外的根节点进入; 每次重写前都经过 rewrite_gate。
  • 视觉: 从固定摄像机观察跳跃弧线和冲刺;敌人的朝向和间距;生命值条与冷却 UI 同步; 开启 Global Invalidation 时没有冻结的 Widget;多人游戏中的双客户端截图一致。

常见错误

错误表现修正
在 GameMode 上保存临时客户端数据客户端什么也看不到使用 GameState 或 PlayerState
使用多播同步门的状态后加入的玩家看到门是关着的使用复制属性 + RepNotify
从玩家强制转换到可选 Blueprint加载时间长,占用内存使用 C++ 基类、接口、IsA(软引用)
“不要使用 Tick”,却让 Timeline 每帧运行开销相同,代码更难减少 Tick 中的 Actor,聚合处理,设置间隔
只在 PossessedBy 中初始化 ASC客户端出现“Can't activate LocalOnly or LocalPredicted ability”使用 AcknowledgePossession 或 OnRep_PlayerState
技能永不结束;在技能中使用 Delay无法再次触发;取消后等待仍会继续确保所有路径都结束技能;使用 Wait Delay
在技能中使用 PlayMontage其他机器上看不到蒙太奇使用 PlayMontageAndWait
在控制台应用 SetByCaller GE伤害为零,并出现缺少 magnitude 的日志使用固定 magnitude 的对应项(GE_Damage_Debug)
查询 GE 授予的标签对错误的效果触发反应使用资产标签;将 asset-tag cvar 设为 0
假设进入条件会被轮询敌人在攻击范围内仍会继续追击在运行状态中使用事件或 On Tick 转换
状态没有失败转换“为什么会转到根状态”明确设置成功和失败转换
在同一状态中将 Delay 放在 MoveTo 旁移动时一直等待使用独立的 Wait 状态;5.6 Task Control Flow
在敌人的 CDO 上设置 C++ 控制器类敌人站着不动使用持有该行为树的控制器 Blueprint;将其放置到场景中或生成
使用 UMG 属性绑定和 widget Tick产生逐帧开销;失效期间会冻结使用属性委托发送事件
经常切换的条使用 Collapsed每次切换都会使布局失效使用 Hidden
在视口 PIE 中测试失效看不到性能提升使用新窗口 PIE
游戏运行时同步保存出现卡顿,有认证风险使用 AsyncSaveGameToSlot
凭感觉认为统计数据有问题就重写浪费精力,没有收益使用 Insights trace 和 rewrite_gate
手动挑选测试阈值正确的构建也会失败根据参数推导阈值
Agent Blueprint 中将计时器写成 Delay 链150 个 Delay 节点(Deiter [00:56:45])使用 Timeline、C++ 计时器或 GAS 任务

交接

  • 接收自 scenario-unreal-animation:角色 Blueprint 子类、带有变量契约的 AnimBP、带根运动和扭曲目标的蒙太奇、在命中帧触发的可复用 AN_SendGameplayEvent 通知;自 scenario-unreal-world-building:带导航边界、玩家起始点、流送范围、Data Layers 的关卡,以及作为 Asset User Data 的游戏数据。
  • 交付给 scenario-unreal-vfx:事件契约(vfx_event_contract:标签、触发器、载荷、来自游戏数据的半径、窗口、最大速率、生成路径;提示效果仅用于外观);给 scenario-unreal-performance:Development 构建、作为自动化测试的最坏情况场景、其 Insights 跟踪、Tick 统计、AI 和 ASC 计数(perf_handoff);给 scenario-unreal-animation:调优后的移动模型,先于运动匹配数据(DeVoe FLDXtAV7qsw [00:07:01]);给 scenario-unreal-pipeline-automation:用于 CI 的自动化测试。

UE 5.8 说明

  • 复制属性自动注册(5.6);Iris 对被许可方已可用于生产,但通用复制仍为默认选项;Mover 仍为 Experimental。
  • Enhanced Input 与 Common UI 统一(可用于生产);Combo 触发器已弃用;UPlayerMappableInputConfig 已弃用(5.4)。
  • GAS:NonInstanced 能力已弃用(5.5);冷却 GE 验证(5.7);Blueprint 中的 GetAssetTags 和 GetGrantedTags(5.7);调试命令位于 AbilitySystem.Ability 和 AbilitySystem.Effect 下(5.4)。
  • StateTree:Task Control Flow 和计划 Tick(5.6);Rewind Debugger 跟踪(5.7);按标签设置起始状态、可逆绑定、UE::StateTree::EComparisonOperator(5.8)。
  • Blueprint:已移除原生化(5.4);IsA (Soft)(5.5);空 Tick 不产生开销(5.6);BlueprintGraphEditor、不允许局部变量遮蔽成员、bp.MaxAsyncActionCount(5.8)。

参考资料

评论

支持 Markdown