roblox-gui

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Roblox GUI Reference

Roblox GUI参考

GUI Container Types

GUI容器类型

ContainerParentUse Case
ScreenGui
PlayerGui
HUDs, menus, overlays — always faces screen
SurfaceGui
BasePart
World-space UI on a part surface (signs, screens)
BillboardGui
BasePart
or
Model
Floats above a part in 3D space (name tags, health bars)
容器父级使用场景
ScreenGui
PlayerGui
HUD、菜单、覆盖层——始终朝向屏幕
SurfaceGui
BasePart
零件表面的世界空间UI(标识牌、显示屏)
BillboardGui
BasePart
Model
悬浮在3D空间零件上方的UI(名称标签、血量条)

ScreenGui

ScreenGui

lua
-- 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
lua
-- 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

SurfaceGui

lua
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
lua
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

BillboardGui

lua
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

lua
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 Sizing and Positioning

UDim2尺寸与定位

UDim2.new(xScale, xOffset, yScale, yOffset)
— scale is 0–1 relative to parent, offset is pixels.
lua
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 shifts the element's pivot (0–1 on each axis):
lua
frame.AnchorPoint = Vector2.new(0.5, 0.5)   -- pivot at center
frame.Position    = UDim2.fromScale(0.5, 0.5)  -- truly centered on screen

UDim2.new(xScale, xOffset, yScale, yOffset)
—— scale取值0-1,为相对于父元素的比例,offset单位为像素。
lua
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):
lua
frame.AnchorPoint = Vector2.new(0.5, 0.5)   -- pivot at center
frame.Position    = UDim2.fromScale(0.5, 0.5)  -- truly centered on screen

Responsive Design

响应式设计

Prefer scale over offset so UI adapts to all screen sizes.
lua
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

优先使用scale而非offset,这样UI可以适配所有屏幕尺寸。
lua
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 Animations

TweenService动画

lua
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

lua
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 Placement

LocalScript放置位置

LocationNotes
StarterGui
Cloned into
PlayerGui
on join; use
ResetOnSpawn = false
to persist
StarterPlayerScripts
Runs once, not reset on respawn; good for persistent managers
StarterCharacterScripts
Re-runs each spawn; suited for character-dependent UI
lua
-- 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)

位置说明
StarterGui
玩家加入时克隆到
PlayerGui
中;设置
ResetOnSpawn = false
可保持常驻
StarterPlayerScripts
仅运行一次,重生时不会重置;适合常驻管理器逻辑
StarterCharacterScripts
每次玩家重生时重新运行;适合依赖角色的UI逻辑
lua
-- 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

ResetOnSpawn属性

lua
screenGui.ResetOnSpawn = false  -- persist across respawns (inventory, settings)
screenGui.ResetOnSpawn = true   -- re-create on respawn (respawn timer) — default

lua
screenGui.ResetOnSpawn = false  -- 重生时保留GUI(适合背包、设置界面)
screenGui.ResetOnSpawn = true   -- 重生时重新创建GUI(适合重生计时器)—— 默认值

Common Patterns Quick Reference

常见模式速查

PatternKey Setup
Full-screen overlay
Size = UDim2.fromScale(1,1)
,
Position = UDim2.fromScale(0,0)
Bottom-center HUD bar
AnchorPoint = (0.5,1)
,
Position = UDim2.new(0.5,0,1,-10)
Padded list
UIPadding
+
UIListLayout
inside a Frame
Scrollable list
ScrollingFrame
+
UIListLayout
; set
CanvasSize
from
UIListLayout.AbsoluteContentSize
Rounded corners
UICorner
with
CornerRadius = UDim.new(0, 8)
Scaled text
TextScaled = true
on TextLabel/TextButton so font grows with container
Dynamic frame height
AutomaticSize = Enum.AutomaticSize.Y
so frame expands to fit children
Health barNested frames: outer = background, inner tweened by
Size.X.Scale
Name tag
BillboardGui
on Head,
StudsOffset = Vector3.new(0, 2.5, 0)

模式核心配置
全屏覆盖层
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
补间动画控制进度
名称标签头部挂载
BillboardGui
,设置
StudsOffset = Vector3.new(0, 2.5, 0)

Common Mistakes

常见错误

MistakeFix
GUI disappears on respawnSet
ResetOnSpawn = false
or use
StarterPlayerScripts
UI looks wrong on mobileUse
UDim2.fromScale
+
UIAspectRatioConstraint
Script can't find
PlayerGui
Use
player:WaitForChild("PlayerGui")
Tween doesn't runEnsure the property is tweenable;
Text
is not,
Position
and
Size
are
BillboardGui visible through wallsVerify
AlwaysOnTop = false
AbsoluteSize
is zero on first frame
Read it inside
task.defer
or after first render step
Clicks pass through overlapping framesAdd a transparent input-blocking Frame or set
Modal = true
SurfaceGui flickersSet
LightInfluence = 0
; ensure part isn't too thin
Text tiny on mobileSet
TextScaled = true
— fixed
TextSize
doesn't adapt to screen size
UI hard to test on mobileUse Studio's Device Emulator (Test tab → Device) to preview layouts
错误修复方案
GUI在玩家重生时消失设置
ResetOnSpawn = false
或使用
StarterPlayerScripts
UI在移动端显示异常使用
UDim2.fromScale
+
UIAspectRatioConstraint
脚本找不到
PlayerGui
使用
player:WaitForChild("PlayerGui")
补间动画不运行确认属性支持补间;
Text
不支持,
Position
Size
支持
BillboardGui可穿墙显示检查
AlwaysOnTop = false
是否设置
首帧
AbsoluteSize
为0
task.defer
中读取,或等待首次渲染步骤完成后读取
点击事件穿透重叠框架添加透明的输入拦截Frame,或设置
Modal = true
SurfaceGui闪烁设置
LightInfluence = 0
;确认挂载零件厚度不要太薄
移动端文本过小开启
TextScaled = true
——固定
TextSize
无法适配屏幕尺寸
UI难以在移动端测试使用Studio的设备模拟器(测试选项卡→设备)预览布局