Why use SurfaceGui?
SurfaceGui projects UI onto a BasePart face, useful for signs and in-world displays. For interactive controls, place the SurfaceGui in PlayerGui and set Adornee to the part.
Try it in Roblox Studio
Create a Part named Display in Workspace. Put this LocalScript in StarterPlayerScripts and run a Studio client.
Syntax
surface.Adornee = part
surface.Face = Enum.NormalId.FrontExamples
SurfaceGui
Put a text display on the front face of a part.
local playerGui = game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui")
local part = workspace:WaitForChild("Display")
assert(part:IsA("BasePart"))
local surface = Instance.new("SurfaceGui")
surface.Adornee = part
surface.Face = Enum.NormalId.Front
surface.Parent = playerGui
local label = Instance.new("TextLabel")
label.Size = UDim2.fromScale(1, 1)
label.Text = "Welcome"
label.Parent = surface- Adornee identifies the Part and Face chooses its front surface.
- The label fills the SurfaceGui and displays text on that surface.
- Parenting the SurfaceGui to PlayerGui also supports interactive descendants; a visual-only sign may instead be organized under the part.
Best practices
- Orient the part so the chosen Face is visible to players.
- Test text legibility at the expected camera distance.
Runtime & versions
Luau host; Roblox engine examples require Roblox Studio. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
Luau documentation