关于 roblox-gui
面向 Roblox GUI 开发的参考技能,涵盖容器选择、尺寸与定位、自适应布局、动画及常见实现模式,适用于制作屏幕界面和世界空间界面的开发者。
主要功能
- 01选择 ScreenGui、SurfaceGui 或 BillboardGui
- 02使用 UDim2 设置尺寸与位置
- 03构建自适应布局
- 04使用 TweenService 制作动画
- 05设置 GUI 在重生后的保留方式
适用场景
- 01创建屏幕 HUD 或菜单
- 02在零件或角色上放置标签
- 03让界面适配移动端尺寸
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ flatbedj/ roblox-skills --skill roblox-gui安装后在 Claude Code 中输入/roblox-gui确认已加载。
详细介绍
Roblox GUI 参考
原生 Robux 符号
在文本标签和按钮中使用 Roblox 原生 Robux 字形,而不要使用图片
图标:utf8.char(0xE002)(等效的 Luau 字符串转义为 "\u{E002}")。
将该字形与价格放在同一个文本对象中,这样间距、缩放和
区域价格更新就能保持同步。
GUI 容器类型
| 容器 | 父级 | 用途 |
|---|---|---|
ScreenGui | PlayerGui | HUD、菜单、叠加层 — 始终面向屏幕 |
SurfaceGui | BasePart | 零件表面上的世界空间 UI(标志、屏幕) |
BillboardGui | BasePart 或 Model | 在 3D 空间中悬浮于零件上方(名称标签、生命值条) |
ScreenGui
-- LocalScript in StarterGui or StarterPlayerScripts
local player = game:GetService("Players").LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "HUD"
screenGui.ResetOnSpawn = false -- keep GUI across respawns
screenGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
screenGui.Parent = playerGui
SurfaceGui
local surfaceGui = Instance.new("SurfaceGui")
surfaceGui.Face = Enum.NormalId.Front
surfaceGui.SizingMode = Enum.SurfaceGuiSizingMode.PixelsPerStud
surfaceGui.PixelsPerStud = 50
surfaceGui.Parent = workspace.ScreenPart
local label = Instance.new("TextLabel")
label.Size = UDim2.fromScale(1, 1)
label.Text = "Hello World"
label.Parent = surfaceGui
BillboardGui
local billboard = Instance.new("BillboardGui")
billboard.Size = UDim2.fromOffset(200, 50)
billboard.StudsOffset = Vector3.new(0, 2.5, 0) -- float above head
billboard.AlwaysOnTop = false
billboard.Parent = character:WaitForChild("Head")
local nameLabel = Instance.new("TextLabel")
nameLabel.Size = UDim2.fromScale(1, 1)
nameLabel.BackgroundTransparency = 1
nameLabel.Text = player.DisplayName
nameLabel.Parent = billboard
UDim2 尺寸与位置
UDim2.new(xScale, xOffset, yScale, yOffset) — scale 是相对于父级的 0–1,offset 是像素值。
frame.Size = UDim2.new(1, 0, 0, 50) -- full width, 50px tall
frame.Position = UDim2.new(0, 0, 0, 0) -- top-left corner
frame.Size = UDim2.fromScale(0.6, 0.4) -- 60% wide, 40% tall
frame.Position = UDim2.new(0.2, 0, 0.3, 0) -- centered (0.2 = (1-0.6)/2)
UDim2.fromScale(0.5, 0.5) -- scale only
UDim2.fromOffset(300, 150) -- pixels only
AnchorPoint 用于移动元素的枢轴点(每个轴的取值为 0–1):
frame.AnchorPoint = Vector2.new(0.5, 0.5) -- pivot at center
frame.Position = UDim2.fromScale(0.5, 0.5) -- truly centered on screen
响应式设计
优先使用 scale 而非 offset,让 UI 能适配所有屏幕尺寸。
button.Size = UDim2.fromScale(0.2, 0.07)
button.Position = UDim2.new(0.4, 0, 0.85, 0)
-- Prevent distortion with UIAspectRatioConstraint
local arc = Instance.new("UIAspectRatioConstraint")
arc.AspectRatio = 4 -- width:height = 4:1
arc.Parent = button
TweenService 动画
local TweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local menuFrame = script.Parent
local function openMenu()
TweenService:Create(menuFrame, tweenInfo, {
Position = UDim2.new(0.05, 0, 0.1, 0)
}):Play()
end
local function closeMenu()
TweenService:Create(menuFrame, tweenInfo, {
Position = UDim2.new(-0.5, 0, 0.1, 0)
}):Play()
end
-- Animated progress bar
local function setProgress(bar, pct)
TweenService:Create(bar, TweenInfo.new(0.2), {
Size = UDim2.new(pct, 0, 1, 0)
}):Play()
end
LocalScript 放置位置
| 位置 | 说明 |
|---|---|
StarterGui | 玩家加入时会克隆到 PlayerGui;设置 ResetOnSpawn = false 可使其持久保留 |
StarterPlayerScripts | 运行一次,不会在重生时重置;适合持久化管理器 |
StarterCharacterScripts | 每次生成角色时都会重新运行;适用于依赖角色的 UI |
-- Safe pattern: wait for character
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
humanoid.HealthChanged:Connect(function(health)
-- update health bar
end)
ResetOnSpawn
screenGui.ResetOnSpawn = false -- persist across respawns (inventory, settings)
screenGui.ResetOnSpawn = true -- re-create on respawn (respawn timer) — default
常见模式速查
| 模式 | 关键设置 |
|---|---|
| 全屏叠加层 | Size = UDim2.fromScale(1,1)、Position = UDim2.fromScale(0,0) |
| 底部居中 HUD 栏 | AnchorPoint = (0.5,1)、Position = UDim2.new(0.5,0,1,-10) |
| 带内边距的列表 | Frame 内使用 UIPadding + UIListLayout |
| 可滚动列表 | ScrollingFrame + UIListLayout;根据 UIListLayout.AbsoluteContentSize 设置 CanvasSize |
| 圆角 | 使用 UICorner,并设置 CornerRadius = UDim.new(0, 8) |
| 缩放文本 | 在 TextLabel/TextButton 上设置 TextScaled = true,让字体随容器放大 |
| 动态框架高度 | 设置 AutomaticSize = Enum.AutomaticSize.Y,让框架扩展以适应子项 |
| 生命值条 | 嵌套框架:外层 = 背景,内层通过 Size.X.Scale 执行动画 |
| 名称标签 | 在 Head 上放置 BillboardGui,并设置 StudsOffset = Vector3.new(0, 2.5, 0) |
常见错误
| 错误 | 修复方法 |
|---|---|
| GUI 在重生后消失 | 设置 ResetOnSpawn = false,或使用 StarterPlayerScripts |
| UI 在移动设备上显示异常 | 使用 UDim2.fromScale + UIAspectRatioConstraint |
脚本无法找到 PlayerGui | 使用 player:WaitForChild("PlayerGui") |
| Tween 未运行 | 确保属性支持 Tween;Text 不支持,Position 和 Size 支持 |
墙壁会遮挡 BillboardGui | 确认 AlwaysOnTop = false |
首帧的 AbsoluteSize 为零 | 在 task.defer 中或首个渲染步骤后读取 |
| 点击穿透重叠的框架 | 添加透明的输入拦截 Frame,或设置 Modal = true |
SurfaceGui 闪烁 | 设置 LightInfluence = 0;确保零件没有太薄 |
| 文本在移动设备上太小 | 设置 TextScaled = true — 固定的 TextSize 不会适配屏幕尺寸 |
| 难以在移动设备上测试 UI | 使用 Studio 的 设备模拟器(Test 标签页 → Device)预览布局 |
评论
支持 Markdown