关于 scenario-roblox-ui
面向 Roblox Studio 的界面与输入技能,帮助开发者构建并评估适配不同设备尺寸的 UI。它结合单一自适应 UI 树、StyleSheet 样式、Input Action 上下文以及布局审计和交互测试。
主要功能
- 01适配不同设备预设的布局
- 02StyleSheet 令牌、主题与选择器
- 03Input Action 上下文和绑定
- 04布局与无障碍 UI 审计
- 05鼠标、键盘和手柄测试
适用场景
- 01为不同屏幕构建菜单和 HUD
- 02检查安全区域与触控控件重叠
- 03测试菜单打开时的输入行为
- 04检查对比度与翻译文本溢出
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-roblox-ui安装后在 Claude Code 中输入/scenario-roblox-ui确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdplayer-settings.mdprocedures.mdscreen-budget.mdsources.mdscripts/rbx_ui.pyscripts/agentkit/ui/UIAudit.luauUIInput.luauUIKit.luauUILayout.luauUISettings.luauUIStyle.luauscripts/agentkit/ui/templates/BuildMenuHud.luauCatalog.luauMenuController.luauShopServer.luau详细介绍
Roblox 界面与输入
在 macOS 上使用 Roblox Studio(2026 年 10 月版),通过 scenario-roblox-expert 工具包进行操作。
这里所说的专家级,是指构建一套运行时可读取屏幕和玩家输入的 UI 树,并通过数据和截图,在不拥有任何设备的情况下,验证其在横竖屏手机、平板、PC、主机和掌机上的表现。请在 Edit 中将 UI 构建为实例,将外观放在 StyleSheet 中,并将控件放入 Input Action System(IAS)上下文中,然后使用 Studio 的设备预设进行测量,并通过真实的点击和按键来驱动 UI。
如果此处提及的同级技能不在你可用的技能中,请让用户安装该技能
(npx skills add scenario-labs/skills --skill <name>);如果无法获得用户协助,请根据工具架构继续操作,并标明这一缺口。
必备背景: scenario-roblox-expert(通道、审查流程、工具包、当前 Roblox 的陷阱)。
立场(专家观点)
- 一套界面树,根据测量结果调整。 绝不为不同设备分别构建副本(Roblox 移动端圆桌讨论,BsyU-SJ9L-c;RDC 2024 框架小组讨论)。根据
GuiService.ViewportDisplaySize布局,并通过UserInputService.PreferredInput显示提示(Roblox 游戏手柄文档)。手机可能连接控制器,笔记本电脑也可能配备触摸屏(Roblox IAS 问答,KnFJl6z5UN0 [00:10:42]),因此TouchEnabled和IsTenFootInterface都会判断错误。 - 外壳使用 Scale,拇指或视线需要的部分使用 Offset。 面板使用 Scale,并通过
UISizeConstraint限制上限;按钮和文本使用 Offset,确保在手机上仍清晰易读(圆桌讨论 [00:11:15])。约束外层容器,而非其子项(Itz_FloppyFish,BLZl-0cl2DM [00:16:37])。在整个 ScreenGui 上使用UIScale会“把一切都弄坏”(boatbomber,RDC 2024 小组讨论 [00:38:15])。 - 核心触摸控件和顶栏各自占有专属空间。 将自定义触摸按钮放在相对于
JumpButton的位置(Roblox 位置与大小文档)。在 Studio 0.743 的所有预设中测得顶栏内边距为 58 px,而 2023 年圆桌讨论幻灯片上标的是 36(BsyU-SJ9L-c [00:08:20])。使用ScreenInsets.CoreUISafeInsets并进行测量;绝不要硬编码边距。 - 外观由 StyleSheet 决定。 令令牌保存所有重复使用的值,主题由名称相同的令牌表组成,查询选择器(
@ViewportDisplaySizeLarge、@PreferredInputTouch、@ReducedMotionEnabledFalse)负责适配界面(Roblox Style Editor 视频,_k1ea0OIKaU [00:03:52, 00:04:24])。代码中设置的属性优先于所有 StyleRule(StyleSheet 文档;实测)。直接读取会返回未应用样式的值:使用GetStyled读取。 - 输入由一组随界面切换的上下文组成。 游戏玩法上下文的 Priority 设为 2000,菜单上下文设为 3000 并使用
Sink,且只在菜单打开时启用(IAS 文档;derpmonster83,8nqNw6kSKJ0 [00:08:26])。Priority 和 Sink 在上下文上设置;优先级相同时,执行顺序不固定(KnFJl6z5UN0 [00:17:26, 00:29:33])。每个操作都分配一个按键和一个游戏手柄按钮。只有在屏幕上没有其他控件能完成相同操作时,触摸才需要UIButton绑定(例如技能、打开菜单、关闭菜单);对于玩家本来就会点击相应控件的操作(切换标签页、购买时确认),无需快捷键,UIAudit 会将其报告为ias-no-touch信息项。IAS 不会绘制移动端按钮或提示:这些需要自行构建(KnFJl6z5UN0 [00:13:30])。 - 持久 HUD 应是 StarterGui 的直接子项,并设置
ResetOnSpawn = false。 如果将它嵌套在 Folder 中,该标记会被忽略,HUD 仍会重置(屏幕容器文档;实测)。 - 无障碍功能是第二种信息传达渠道。 绝不要只用颜色表示状态(BitwiseAndrea,无障碍圆桌讨论 K1pEI6LVJJA [00:29:24])。不要使用组合键,不要使用 F 键;WASD 和方向键都应支持(同一小组讨论 [00:43:15])。遵循
PreferredTransparency、ReducedMotionEnabled和PreferredTextSize(Roblox 无障碍文档)。对比度应为 4.5:1;对于 24 px 及以上的文本,至少为 3:1 [补充内容,WCAG]。 - 除非项目已在使用框架,否则使用普通实例。 在 Edit 中构建的实例对 MCP 工具可见,因此审计、布局检查和截图都能在 Play 前运行。如果多个屏幕共享快速变化的状态,且团队使用 Rojo 工作,则选择 React(jsdotlua)、Fusion 或 Vide。此时应将游戏数据保留在框架之外(Leif,Ezk3vEOvv8o [00:13:51]),并对自己的代码进行基准测试,而不是运行压力测试(RDC 2024 小组讨论 [00:28:11])。
首先确定
| 输入 | 变更 | 无人说明时的默认值 |
|---|---|---|
| 设备和方向 | 单元格大小、安全区域、StarterGui.ScreenOrientation | 手机横屏和竖屏、平板电脑、PC、主机、掌上设备;Sensor |
| 项目中的 UI 框架 | 构建和测试树的位置 | 无:实例加 StyleSheet |
Workspace.PlayerScriptsUseInputActionSystem | IAS 上的默认控件,菜单可拦截跳跃 | Enabled,在 Rojo 项目中设置(脚本无法写入) |
| 语言 | 文本空间、AutoLocalize | 英文源文本;测试德语和 +40% 伪本地化 |
| UI 美术 | 图像槽、9 切片边距 | 扁平 StyleSheet 风格,稍后添加 Scenario 美术 |
| 无障碍标准 | 对比度、动效、目标尺寸 | 4.5:1、遵循减少动效设置、目标尺寸为 44 px |
流程
完整代码、测试 id 和结果:见 references/procedures.md。每个阶段
都通过 scripts/rbx_ui.py 和负责人使用的工具包运行;L 和 O id 指的是
run_live.py。
- 在 Edit 中构建(P1)。
rbx_ui.build(s)会安装目录、工具包模块、客户端控制器(一个 RunContext 为 Client 的Script)和商店服务,然后运行 BuildMenuHud.luau。HUD 左上角显示状态(仅供显示),右上角是菜单按钮,下方是能力按钮。菜单是一个CanvasGroup面板,标题栏中有选项卡,并包含 Home、Shop 和 Settings 页面。商店是一个ScrollingFrame,其AutomaticCanvasSize = Y,并使用UIGridLayout,单元格大小取自 StyleSheet。动态标签会设置AutoLocalize = false。代码绝不会设置由 StyleRule 管理的属性。门槛:30 个项目、2 个 StyleLink、0 个选择器错误;两个 ScreenGui 都是 StarterGui 的直接子级,且ResetOnSpawn = false。 - 审计(P2)。
rbx_ui.audit(s)会运行 UIAudit.luau(20 条规则:重置、内边距、约束、画布、描边、选择器、选择、对比度、IAS 覆盖与冲突、旧版输入模式)以及负责人的Audit.ui。同一模块也会在 Lune 中对 place 文件运行。门槛:0 个错误和 0 个警告;每条规则各有一项故障的测试夹具必须触发所有规则。 - 布局矩阵(P3)。
rbx_ui.layout_matrix(pt, rbx_ui.DEVICES, scenes, out)会在游戏测试期间通过StudioDeviceSimulatorService设置九种预设。 UILayout.luau 的check随后会标记屏幕外元素、顶栏、安全区域、核心触控控件重叠、目标过小、重叠、裁切和文字过小,并捕获每种状态。使用 Scriptable 绑定驱动场景,因为按键或点击会使PreferredInput从 Touch 切换到其他输入方式。门槛:每个设备和场景均为 0 个警告;触控模式下能力按钮位于JumpButton上方;商店至少显示完整的一行单元格;联系表可读。 - 鼠标(P4)。
pt.mouse使用instance_path"LocalPlayer.PlayerGui.Menu..."点击 PlayerGui 副本。在 Edit 中设置的UIButton绑定会在运行时跟随克隆。门槛:每次点击恰好更改其对应属性;购买时服务器只扣除一次金币。 - 键盘和输入上下文(P5)。
pt.keys会通过 IAS 按键。门槛:冷却期间会拒绝第二次使用;菜单打开时,Q、E 和 Space 绝不会传递到游戏操作或跳跃。 - 尽可能在 Studio 中测试游戏手柄(P6)。 使用
GuiService:Select(grid)开始选择,用方向键移动,按 Return 激活,通过 Scriptable 绑定按下游戏手柄按钮,并在xbox预设下检查字形和尺寸。门槛:焦点在网格中向下和向右移动;选择最后一个项目时画布会滚动;xbox 字形显示为 “X”。摇杆、方向键、ButtonB 和 Select 按钮需要控制器或 Controller Emulator(gui-paths)。 - 样式和主题(P7)。 在运行时使用
UIStyle.setTheme切换主题,它会重新指向设计表的StyleDerive。门槛:两个主题的low-contrast均为 0;通过代码设置的 Size 在所有规则下都能保留。 - 偏好设置和动态效果(P8)。 将装饰元素的透明度乘以
PreferredTransparency;启用减少动态效果时跳过淡入淡出。门槛:启用减少动态效果时,面板在第一帧即为不透明。音量、镜头抖动、按键重绑定和文字大小:参阅 player-settings.md 中的UISettings。 - 重生(P9)。 在服务器上杀死角色,并比较 HUD 重生前后的标记。门槛:只有一个 HUD、状态保留、生命值绑定到新的 Humanoid。
- 本地化(P10)。 使用
LocalizationService:GetTranslatorForLocaleAsync("de")就地翻译,然后将每个可本地化字符串的长度增加 40%,并在两款最小尺寸的手机上测试。门槛:两轮测试中每个页面的text-clipped均为 0。 - 场景 UI 美术资源(P12)。 道具图标、边框和按钮皮肤取自 scenario-game-assets,格式为透明 PNG。只有获得用户同意后才上传,然后为每个单元格设置
Icon.Image,并为边框设置ScaleType = Slice和SliceCenter。美术资源中不要包含文字。
数值
| 数值 | 相对于 | 来源 |
|---|---|---|
| 所有预设的顶栏内嵌距离均为 58 px | GuiService.TopbarInset,Studio 0.743 | 实测(2023 年幻灯片:36) |
| iPhone 7 为 666x374,iPhone 14 为 749x388(竖屏 388x762),Galaxy A06 为 705x338 | 视口,模拟器预设 | 实测 |
| iPad 第 10 代为 1179x819,笔记本电脑为 1365x768,1080p 和 Xbox 为 1919x1079 | 视口,模拟器预设 | 实测 |
| Small:手机和掌上设备;Medium:iPad、笔记本电脑、1080p;Large:Xbox | ViewportDisplaySize | 实测 |
手机上 JumpButton 为 70 px,位置是 (1,-95, 1,-90);iPad 上为 120 px,位置是 (1,-170, 1,-210) | 屏幕角落 | 实测 |
| 虚拟摇杆区域:宽度左侧 40% | 视口宽度 | 实测帧,限制范围 [新增] |
| 手机上可以触及屏幕顶部以下 40% 的位置,平板上则不行 | 屏幕高度 | 位置与尺寸文档 |
| 目标区域为 44 px,文本最小为 11 px | 绝对像素 | [新增,Apple HIG] |
| 对比度 4.5:1;24 px 及以上为 3:1 | 文本与其背景 | [新增,WCAG] |
| 菜单上下文优先级为 3000,游戏内容上方的 Sink 为 2000 | InputContext.Priority | IAS 文档(2000 高于默认脚本) |
| CAS 优先级:Low 为 1000,Medium 为 2000,High 为 3000 | Enum.ContextActionPriority | 参考资料(“0 到 100”的教程有误) |
| 单元格为 88x100、96x112、140x160;技能为 64 和 88 px | Small、Medium、Large 显示尺寸 | 模板 [新增] |
淡出时间为 0.2 s;暗化程度为 0.45 x PreferredTransparency | 菜单打开时 | 模板 [新增] |
| 长度 +40% | 源字符串 | 伪本地化 [新增] |
| 自动翻译配额按语言统计字符数 | 字符 | 自动翻译文档 |
质量门槛
可测量项:
run_live.py的 L0 到 L14 和run_offline.sh的 O1 到 O3 均通过。- UIAudit 和负责人提供的
Audit.ui报告中,警告和错误均为 0。 UILayout.check在两个场景的九种预设上均报告 0 条警告。- 在两种最小尺寸的手机上使用德语和伪本地化时,
text-clipped数量为 0;两种主题下的low-contrast数量均为 0。 - 你的脚本没有控制台错误。FoundationProvider 和 UIBlox 相关行来自 Studio 自带的核心脚本。
视觉检查:对照 critique.md 阅读 HUD 和商店的联系表(最多 1,600 px)。永久显示元素、聊天区域和商店发现功能:参见 screen-budget.md。检查文本是否清晰易读、是否有内容位于触控控件或顶栏下方、主要操作按钮是否最大,以及是否无需依靠颜色也能识别稀有度。
常见错误
| 错误 | 表现 | 修复 |
|---|---|---|
| 代码设置了 StyleRule 所拥有的属性 | 切换主题时会跳过该对象 | 交由规则处理 |
在应用样式的对象上读取 obj.BackgroundColor3 | 返回默认颜色 | obj:GetStyled("BackgroundColor3") |
| 将 HUD ScreenGui 放在 Folder 内 | 尽管设置了标记,重生后仍会重置 | 将其直接设为 StarterGui 的子级 |
使用 MouseButton1Click 作为按钮处理程序 | 手柄和触控的操作路径不同 | 使用 Activated,或使用 IAS UIButton 绑定 |
使用 TouchEnabled 决定布局 | 触控笔记本会显示手机界面 | 使用 PreferredInput、ViewportDisplaySize |
| 触控测试期间按下按键 | PreferredInput 会切换为 KeyboardAndMouse | 使用 Scriptable InputBinding:Fire |
| 菜单隐藏触控控件后未恢复 | 关闭菜单后跳跃按钮消失 | 关闭时恢复 TouchControlsEnabled |
| 两个处于同一 Priority 的上下文共用一个按键 | 两个操作中的任意一个都会触发 | 使用不同的优先级,并让优先级较高的操作使用 Sink |
网格布局使用 AutomaticCanvasSize = None | 无法访问最后的项目 | 使用 AutomaticCanvasSize = Y |
文本使用较粗的 UIStroke 和 Round 接合 | 重叠部分透出 | LineJoinMode 使用 Miter 或 Bevel(Stewiepfing,9kuWl_t1AOE [00:00:12]) |
数字和名称启用 AutoLocalize | 翻译表中出现无用条目 | 对动态标签设置 AutoLocalize = false |
| 选择器拼写错误 | 规则不起作用;SelectorError 通常显示为 "" | UIStyle.errors 会重新赋值、等待,然后读取 |
绑定为 IAS UIButton 的按钮上使用 Activated 处理程序 | 会晚一次点击触发(观察所得) | 处理 InputAction |
| 在启动时一次性放置能力按钮 | 旋转设备或切换输入方式后,按钮不再位于跳跃按钮上方 | 在 Camera.ViewportSize 和 PreferredInput 变化时重新放置(模板;在 iPhone 14 竖屏上测量时,按钮位于跳跃按钮上方) |
交接
- 输入:作为玩家属性的金币和所有权(持久化来自 scenario-roblox-data)、远程验证规则(scenario-roblox-networking)、能力名称和冷却时间(scenario-roblox-gameplay)、Robux 提示(scenario-roblox-monetization)、点击和购买音效(scenario-roblox-vfx-audio)、图标、框架和按钮皮肤(scenario-game-assets)、项目布局和 Rojo(scenario-roblox-architecture、scenario-roblox-tooling)。
- 输出:将带有 Scriptable 测试绑定的 InputActions 交给 scenario-roblox-gameplay;将低端手机上的 UI 成本交给 scenario-roblox-performance;将屏幕打开和关闭属性交给 scenario-roblox-monetization,用于转化漏斗。
当前 Roblox 注意事项
- IAS 于 2026-06-11 正式发布。
InputAction:Fire已弃用:改为触发 ScriptableInputBinding。预计 2027 年初默认启用 IAS 默认脚本。BindActivate和游戏手柄选择切换目前还没有 IAS 对应实现(KnFJl6z5UN0 [00:20:15, 00:39:43])。 PreferredInput(2025-10-14)和ViewportDisplaySize(2025-08-14)取代了设备检测。- 未设置的
InputBinding.KeyCode读取为None,而不是文档所述的Unknown。实测中,InputActionLabel.ResolvedText读取为空,因此字形来自InputAction.PreferredBinding(实测)。 StudioDeviceSimulatorService(PluginSecurity)可在 Edit 和 playtest Client 中通过execute_luau驱动 Device Simulator;Server 会被拒绝。无论ScreenOrientation如何设置,模拟器都会旋转(实测)。- 新 place 的
ScreenOrientation为LandscapeSensor;参考资料中写的是 Sensor。 - 对于已存在于 place 中的规则,Selector 发生变化后,
StyleRule.SelectorError会在几帧后填入内容;若提前设置,损坏的 selector 会读取为 ""(实测)。 execute_luau无法读取PlayerScriptsUseInputActionSystem,也无法写入GuiService首选项:请在 Rojo 中设置该标志,并通过游戏内设置测试首选项。- MCP
user_keyboard_input和VirtualInput只发送键盘事件:游戏手柄 KeyCodes 不会到达 IAS(实测)。
参考资料
- references/procedures.md:P0 至 P12,包含完整代码、测试 ID 和结果。
- references/expert-notes.md:每位专家和文档所传授的内容及时间戳。
- references/critique.md:评估 UI 构建及其截图的评分标准。
- references/player-settings.md:音量、镜头抖动、重新绑定、文本大小。
- references/screen-budget.md:减少 HUD 元素、聊天区域、商店发现、购买反馈。
- references/gui-paths.md:Studio GUI 中的 Device Simulator、Controller Emulator、Style Editor、IAS 和本地化。
- references/sources.md:所有来源、凭据、URL 和最佳时间戳。
- scripts/rbx_ui.py:构建、审计、设备列表、模拟、布局矩阵、对比度。
- scripts/agentkit/ui/:UIKit、UIStyle、UIInput、UILayout、UIAudit、UISettings,以及模板(BuildMenuHud、MenuController、ShopServer、Catalog)。