mcpField
R
roblox-ui

roblox-ui

github.com/el4cteo设计与 UI56558 次安装2 周前更新
代码仓库

关于 roblox-ui

面向 Roblox 开发者的 UI 设计与实现指南,涵盖自适应布局、样式、跨平台输入、文本、动画和性能。适用于从单个界面到多页面项目。

主要功能

  1. 01使用 Scale 与约束适配屏幕
  2. 02通过布局组件组织界面
  3. 03用 StyleSheets 管理样式和主题
  4. 04适配触摸、键鼠与手柄输入
  5. 05处理文本、本地化及动画
  6. 06优化动态界面的性能

适用场景

  1. 01构建适配手机和大屏的 HUD
  2. 02制作支持手柄导航的菜单
  3. 03为多页面项目统一样式
  4. 04实现动画面板与世界空间 UI

安装

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

$npx skills add https://github.com/el4cteo/roblox-skills --skill roblox-ui

安装后在 Claude Code 中输入/roblox-ui确认已加载。

附带文件references/styling-and-frameworks.md

详细介绍

Roblox UI

基础

  • 将 UI 放在 StarterGui 中作为 ScreenGui(会复制到每位玩家的 PlayerGui),或通过客户端控制器创建。UI 代码仅在客户端运行;在常规设计中,服务器不会接触 PlayerGui。
  • ScreenGui 的默认设置:ResetOnSpawn = false(死亡后保留 UI)、ZIndexBehavior = Sibling、按设计设置 IgnoreGuiInset,交互式 UI 使用 ScreenInsets = CoreUISafeInsets(避开刘海屏区域和 Roblox 顶栏);只有全屏背景才使用 DeviceSafeInsets/None。
  • 使用 Scale 设置尺寸和位置(UDim2.fromScale),并搭配约束;Offset 仅用于固定细节(内边距、描边、图标)。纯 Offset UI 在手机和 4K 屏幕上会显示异常。
  • AnchorPoint = Vector2.new(0.5, 0.5) + Position = UDim2.fromScale(0.5, 0.5) 可将元素居中。
  • UIAspectRatioConstraint 可保持形状为正方形或比例一致;UISizeConstraint 可限制尺寸;使用 TextScaled 时,UITextSizeConstraint 可限制文本大小(尽可能优先使用固定的 TextSize + AutomaticSize——TextScaled 会导致大小不一致)。
  • AutomaticSize 可让框架随内容增长(列表、工具提示、聊天气泡)。
  • 在 Device Simulator 中测试每种屏幕(手机竖屏/横屏、平板、10 英尺距离的主机屏幕、4K)。

布局

需求使用
自适应行/列UIListLayout(FillDirection、Padding、HorizontalFlex/VerticalFlex、Wraps)
一个项目扩展以填满空间使用 FlexMode = Fill(或 Grow/Shrink/Custom)的 UIFlexItem 子项
网格(物品栏)在带有 AutomaticCanvasSize 的 ScrollingFrame 中使用 UIGridLayout
轮播/页面UIPageLayout
圆角、边框、内边距UICorner、UIStroke、UIPadding
渐变、阴影UIGradient、UIShadow
缩放整个组UIScale
--!strict
local Players = game:GetService("Players")

local playerGui = Players.LocalPlayer:WaitForChild("PlayerGui")

local screenGui = Instance.new("ScreenGui")
screenGui.Name = "Hud"
screenGui.ResetOnSpawn = false
screenGui.ScreenInsets = Enum.ScreenInsets.CoreUISafeInsets

local bar = Instance.new("Frame")
bar.Name = "Toolbar"
bar.AnchorPoint = Vector2.new(0.5, 1)
bar.Position = UDim2.new(0.5, 0, 1, -16)
bar.Size = UDim2.fromScale(0.6, 0.1)
bar.BackgroundTransparency = 0.3
bar.Parent = screenGui

local list = Instance.new("UIListLayout")
list.FillDirection = Enum.FillDirection.Horizontal
list.HorizontalFlex = Enum.UIFlexAlignment.Fill -- slots share the width equally
list.Padding = UDim.new(0, 8)
list.Parent = bar

Instance.new("UICorner").Parent = bar
local padding = Instance.new("UIPadding")
padding.PaddingLeft, padding.PaddingRight = UDim.new(0, 8), UDim.new(0, 8)
padding.Parent = bar

for slot = 1, 5 do
	local button = Instance.new("TextButton")
	button.Name = `Slot{slot}`
	button.Text = tostring(slot)
	button.Size = UDim2.fromScale(0, 1)
	button.Parent = bar
	Instance.new("UIAspectRatioConstraint").Parent = button
end

screenGui.Parent = playerGui -- parent last: one layout pass, no flicker

样式:StyleSheets(类似 CSS)

Roblox 引擎级样式可替代复制粘贴的属性值:

  • 使用包含 StyleRule 的 StyleSheet(Selector 可设为 "TextButton"、".Primary"(标签)、"#Close"(名称)、"TextButton:Hover"(状态)、"::UICorner"(修饰符伪实例)),并调用 rule:SetProperties({...})。
  • Token 是 Token Sheet 上的属性($Primary、$Radius);主题 是通过 StyleDerive 派生 Token 的 Sheet;通过重新指定 StyleDerive 来切换主题。
  • ScreenGui 下的 StyleLink 会将一个 Sheet 应用于该树。样式查询(@Name)可根据屏幕尺寸、输入类型或无障碍设置切换样式。
  • 在 Studio 的 Style Editor 中进行可视化编辑。详情和代码示例:references/styling-and-frameworks.md。

UI 中的跨平台输入

  • 读取 UserInputService.PreferredInput(KeyboardAndMouse、Touch、Gamepad),并监听 UserInputService:GetPropertyChangedSignal("PreferredInput"),以切换按钮提示和布局。不要仅凭 TouchEnabled/KeyboardEnabled 推断平台。
  • 使用 GuiButton.Activated(支持鼠标、触摸和游戏手柄),而非 MouseButton1Click。
  • 游戏手柄/主机:将每个交互元素设为 Selectable;打开菜单时设置 GuiService.SelectedObject;使用 SelectionGroup/NextSelection* 分组,以实现可预测的方向键导航;支持使用 ButtonB 关闭。触摸目标最小尺寸约为 44×44 px;手机上的文本应不小于 14 px。
  • 通过 Input Action System 绑定操作(InputBinding.UIButton 可让屏幕按钮触发操作)——参见 roblox-input。

文本

  • RichText = true 可启用 <b>、<i>、<font color="#FF0">、<stroke> 等标签。转义用户文本。
  • 向其他玩家显示的任何玩家文本都必须经过过滤:在服务器上使用 TextService:FilterStringAsync(roblox-text-chat)。这包括宠物名称、标牌、公会名称和交易备注。
  • 使用 FontFace = Font.new("rbxasset://fonts/families/GothamSSm.json", Enum.FontWeight.Bold) 设置字重。
  • 使用 LocalizationTable 和自动翻译实现本地化;避免将文本直接嵌入图片中。

动画与手感

  • 在客户端使用补间动画:TweenService:Create(frame, TweenInfo.new(0.2, Enum.EasingStyle.Quad), { Position = ... }):Play()。
  • 使用 UIScale.Scale 制作弹出效果,而不是调整 Size(这样可以保持布局稳定)。
  • CanvasGroup 可淡入淡出整个子树(GroupTransparency),但会渲染到纹理:适合用于淡入淡出面板,不适合用于大型常驻 UI(会带来内存和画质开销)。
  • 现在 ClipsDescendants 也会裁剪旋转后的子对象和 Path2D(自 2026 年 9 月 24 日起为默认行为;StarterGui.ClipsDescendantsSupportsRotation 退出选项将于 2026 年 11 月移除)。若要避免旋转后的子对象被裁剪,可将其设为层级更高的同级对象。旋转后的父对象仍只会在 CanvasGroup 内部进行裁剪。
  • 拖放:使用 UIDragDetector(已弃用的 GuiObject.Draggable 不再适用于新项目)。

世界空间 UI

  • BillboardGui(面向摄像机:名称、生命值条)——谨慎设置 MaxDistance 和 AlwaysOnTop,使用 Size 的 Scale 值按距离缩放;零件上的屏幕或标牌使用 SurfaceGui。优先使用 Adornee,并将其保留在 PlayerGui 中以显示玩家专属内容。当其零件流出时,它们会停止渲染。
  • ProximityPrompt 可免费提供跨平台交互 UI(请在服务端进行验证!)。

框架

屏幕数量超过几个时,声明式框架有助于保持状态与 UI 同步:

  • React(jsdotlua/react + react-roblox)——组件 + hooks,Web 开发者熟悉,适用于大型应用。
  • Fusion——响应式状态对象和声明式实例创建。
  • Vide——小巧、快速的响应式库。 与项目现有的框架保持一致。将游戏状态保存在控制器中;UI 只负责渲染状态并发出用户意图。

性能

  • 如果值没有变化,避免每帧更新文本或属性。
  • 菜单关闭时使用 Visible = false(或对 ScreenGui 使用 Enabled = false),而不是反复销毁并重新创建;大型列表应按需构建或进行虚拟化。
  • 动态 UI 中过多使用 UIGradient/CanvasGroup/UIStroke 会增加帧耗时;请检查 MicroProfiler。

相关技能

roblox-input(操作、游戏手柄)、roblox-text-chat(过滤)、roblox-monetization(商店)、roblox-luau、roblox-performance。

评论

支持 Markdown