Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.
SurfaceGui
Inherits from: SurfaceGuiBase → LayerCollector → GuiBase2d → GuiBase → Instance → Object
SurfaceGui allows for the rendering of UI objects onto a part's surface in the 3D world while also allowing for basic user interaction to occur. Similar to Decals and Textures, UI objects such as TextLabels and ImageLabels parented to a SurfaceGui face the same direction as the surface they're on, editable through the Face property.

Note that interactive UI elements like ImageButtons and TextButtons inside a SurfaceGui will only receive user input if they are parented to the PlayerGui, typically via placing the SurfaceGui inside StarterGui (the Adornee property can be used to target a part in the 3D world while the SurfaceGui itself remains in the PlayerGui). Additionally, the part's CanQuery property must be true for the interactive UI element to receive input.
See In-Experience UI for a guide on working with SurfaceGui containers.
Caching Behavior
To help improve performance, the appearance of a SurfaceGui is cached until one of the following occurs, after which its appearance will be recomputed on the next rendering frame.
- A descendant is added to or removed from the
SurfaceGui. - A property of a descendant of the
SurfaceGuichanges. - A property of the
SurfaceGuiitself changes.
Inherits from: SurfaceGuiBase
Memory category: Instances
Properties
| Name | Type / Returns | Description |
|---|---|---|
| SurfaceGui.AlwaysOnTop | boolean | Determines whether the SurfaceGui will always be rendered on top of other 3D objects. |
| SurfaceGui.Brightness | float | Determines the factor by which the SurfaceGui container's light is scaled when LightInfluence is 0. |
| SurfaceGui.CanvasSize | Vector2 | The size of a "virtual screen" in "virtual pixels" which makes SurfaceGuis pixel-to-pixel compatible with ScreenGuis. |
| SurfaceGui.ClipsDescendants | boolean | Whether portions of GuiObjects that fall outside of the SurfaceGui canvas borders will be drawn. |
| SurfaceGui.LightInfluence | float | Controls how much the SurfaceGui is influenced by environmental lighting. |
| SurfaceGui.MaxDistance | float | Controls how far away the SurfaceGui can be displayed before it stops rendering. |
| SurfaceGui.PixelsPerStud | float | Determines the density of pixels used for each world-space stud to render the contents of the SurfaceGui. |
| SurfaceGui.SizingMode | SurfaceGuiSizingMode | Determines whether the SurfaceGui will render at a fixed size or scale with its size in studs. |
| SurfaceGui.ToolPunchThroughDistance | float | Sets the distance in which left clicking starts acting on the SurfaceGui instead of for the held Tool. |
| SurfaceGui.ZOffset | float | Layers this SurfaceGui in relation to other SurfaceGuis on the same face. |
Inherited from SurfaceGuiBase
| Name | Type / Returns | Description |
|---|---|---|
| SurfaceGuiBase.Active | boolean | Determines whether the SurfaceGui sinks user input; true by default. |
| SurfaceGuiBase.Adornee | Instance | BasePart on which to apply the SurfaceGui, overriding the default parent association. |
| SurfaceGuiBase.Face | NormalId | NormalId face upon which to apply the SurfaceGui. |
Inherited from LayerCollector
| Name | Type / Returns | Description |
|---|---|---|
| LayerCollector.Enabled | boolean | Toggles the visibility of this LayerCollector. |
| LayerCollector.ResetOnSpawn | boolean | Determines if the LayerCollector resets (deletes itself and re-clones into the player's PlayerGui) every time the player's character respawns. |
| LayerCollector.ZIndexBehavior | ZIndexBehavior | Controls how GuiObject.ZIndex behaves on all descendants of this LayerCollector. |
Inherited from GuiBase2d
| Name | Type / Returns | Description |
|---|---|---|
| GuiBase2d.AbsolutePosition | Vector2 | Describes the actual screen position of a GuiBase2d element, in pixels. |
| GuiBase2d.AbsoluteRotation | float | Describes the actual screen rotation of a GuiBase2d element, in degrees. |
| GuiBase2d.AbsoluteSize | Vector2 | Describes the actual screen size of a GuiBase2d element, in pixels. |
| GuiBase2d.AutoLocalize | boolean | When set to true, localization will be applied to this GuiBase2d and its descendants. |
| GuiBase2d.Localize | boolean | Automatically set to true when a localization table's LocalizationTable.Root targets this object, or an ancestor of this object. |
| GuiBase2d.RootLocalizationTable | LocalizationTable | A reference to a LocalizationTable to be used to apply automated localization to this GuiBase2d and its descendants. |
| GuiBase2d.SelectionBehaviorDown | SelectionBehavior | Customizes gamepad selection behavior in the down direction. |
| GuiBase2d.SelectionBehaviorLeft | SelectionBehavior | Customizes gamepad selection behavior in the left direction. |
| GuiBase2d.SelectionBehaviorRight | SelectionBehavior | Customizes gamepad selection behavior in the right direction. |
| GuiBase2d.SelectionBehaviorUp | SelectionBehavior | Customizes gamepad selection behavior in the up direction. |
| GuiBase2d.SelectionGroup | boolean | Allows customization of gamepad selection movement. |
Inherited from Instance
| Name | Type / Returns | Description |
|---|---|---|
| Instance.Archivable | boolean | Determines if an Instance and its descendants can be cloned using Instance:Clone(), and can be saved/published. |
| Instance.archivable | boolean | |
| Instance.Capabilities | SecurityCapabilities | The set of capabilities allowed to be used for scripts inside this container. |
| Instance.IsInSandbox | boolean | Indicates whether the instance is inside a sandboxed container. |
| Instance.Name | string | A non-unique identifier of the Instance. |
| Instance.Parent | Instance | Determines the hierarchical parent of the Instance. |
| Instance.PredictionMode | PredictionMode | Reflects the client-side prediction mode applied to the instance under server-authoritative physics. |
| Instance.RobloxLocked | boolean | A deprecated property that used to protect CoreGui objects. |
| Instance.Sandboxed | boolean | When enabled, the instance can only access abilities in its Capabilities list. |
| Instance.UniqueId | UniqueId | A unique identifier for the instance. |
Inherited from Object
| Name | Type / Returns | Description |
|---|---|---|
| Object.ClassName | string | A read-only string representing the class this Object belongs to. |
| Object.className | string |
SurfaceGui.AlwaysOnTop
This property determines whether the SurfaceGui will always render on top of other 3D objects.
When set to false (default), the SurfaceGui renders like other 3D content and is occluded by other 3D objects. When set to true, the SurfaceGui always renders on top of 3D content and the appearance changes significantly:
- Colors match how they appear inside a
ScreenGui. - Text may appear sharper on high DPI devices.
LightInfluenceis treated as though it's0.Brightnesshas no effect.
| Field | Value |
|---|---|
| type | boolean |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Data |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.Brightness
This property determines the factor by which the SurfaceGui container's light is scaled when LightInfluence is 0. By default, this property is 1 and can be set to any number between 0 and 1000. By modifying this property, the apparent brightness of a SurfaceGui can be better matched to its environment. For instance, a video billboard can be brightened inside a dark room by increasing Brightness to 10.
Note that Brightness is inaccessible in Studio and has no effect when either LightInfluence is 1 or AlwaysOnTop is true.
| Field | Value |
|---|---|
| type | float |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Data |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.CanvasSize
The size of a "virtual screen" in "virtual pixels" which makes SurfaceGuis pixel-to-pixel compatible with ScreenGuis.
| Field | Value |
|---|---|
| type | Vector2 |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Sizing |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.ClipsDescendants
When set to true (default), portions of GuiObjects that fall outside of the SurfaceGui canvas borders will not be drawn.
Even when this property is false, GuiObjects that are completely outside of the canvas will not render.
| Field | Value |
|---|---|
| type | boolean |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Behavior |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.LightInfluence
Controls how much the SurfaceGui is influenced by environmental lighting, in a range from 0 to 1. Setting this to 1 means that surrounding lighting has complete control over the appearance, while setting it to 0 means that the lighting has no effect.
| Field | Value |
|---|---|
| type | float |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Data |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.MaxDistance
This property controls how far from the camera the SurfaceGui will be displayed before it stops rendering. A value of 0 means there is no limit and it will render infinitely far away. The default value of 1000 works fine for most cases.
For SurfaceGuis that appear outdoors, it's recommended that MaxDistance is high enough to ensure that the container's UI is sufficiently small on the screen when it appears or disappears, minimizing the sudden pop‑in/out effect.
| Field | Value |
|---|---|
| type | float |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Data |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.PixelsPerStud
This property determines the density of pixels used for each world-space stud to render the contents of the SurfaceGui. Higher values will cause the various GuiObjects within to appear smaller if they are kept the same size. Conversely, lower values will cause objects to appear larger. However, if the GuiObjects are scaled proportionally through use of UIScale, GuiObject.Size, TextLabel.TextSize, or similar, this property allows for higher definition to be used.
It's important to select a value based on how far away you expect a player to view the SurfaceGui. Also be mindful that a large pixel density could negatively affect performance if the face of the adorned part is large enough.
| Field | Value |
|---|---|
| type | float |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Sizing |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.SizingMode
When set to SurfaceGuiSizingMode.PixelsPerStud (default), the SurfaceGui renders with a variable size based on PixelsPerStud and the surface's size in studs.
When set to SurfaceGuiSizingMode.FixedSize, the SurfaceGui renders with a fixed size set through CanvasSize.
| Field | Value |
|---|---|
| type | SurfaceGuiSizingMode |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Sizing |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.ToolPunchThroughDistance
Sets the distance in which left clicking starts acting on the SurfaceGui instead of for the held Tool. If a character is within this distance of the SurfaceGui, the Tool will not activate on click.
| Field | Value |
|---|---|
| type | float |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Data |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
SurfaceGui.ZOffset
Layers this SurfaceGui in relation to others on the same face (changing this does not visually "lift" or "sink" a SurfaceGui from the surface).
| Field | Value |
|---|---|
| type | float |
| security | {"read":"None","write":"None"} |
| thread safety | ReadSafe |
| category | Appearance |
| serialization | {"can_load":true,"can_save":true} |
| capabilities | ["UI"] |
Methods
Inherited from LayerCollector
| Name | Type / Returns | Description |
|---|---|---|
| LayerCollector:GetLayoutNodeTree | Dictionary |
Inherited from Instance
| Name | Type / Returns | Description |
|---|---|---|
| Instance:AddTag | () | Applies a tag to the instance. |
| Instance:children | Instances | Returns an array of the object's children. |
| Instance:ClearAllChildren | () | This method destroys all of an instance's children. |
| Instance:Clone | Instance | Create a copy of an instance and all its descendants, ignoring instances that are not Archivable. |
| Instance:clone | Instance | |
| Instance:Destroy | () | Sets the Instance.Parent property to nil, locks the Instance.Parent property, disconnects all connections, and calls Destroy() on all children. |
| Instance:destroy | () | |
| Instance:FindFirstAncestor | Instance? | Returns the first ancestor of the Instance whose Instance.Name is equal to the given name. |
| Instance:FindFirstAncestorOfClass | Instance? | Returns the first ancestor of the Instance whose Object.ClassName is equal to the given className. |
| Instance:FindFirstAncestorWhichIsA | Instance? | Returns the first ancestor of the Instance for whom Object:IsA() returns true for the given className. |
| Instance:FindFirstChild | Instance? | Returns the first child of the Instance found with the given name. |
| Instance:findFirstChild | Instance | |
| Instance:FindFirstChildOfClass | Instance? | Returns the first child of the Instance whose ClassName is equal to the given class name. |
| Instance:FindFirstChildWhichIsA | Instance? | Returns the first child of the Instance for whom Object:IsA() returns true for the given className. |
| Instance:FindFirstDescendant | Instance? | Returns the first descendant found with the given Instance.Name. |
| Instance:GetActor | Actor? | Returns the Actor associated with the Instance, if any. |
| Instance:GetAttribute | Variant | Returns the value which has been assigned to the given attribute name. |
| Instance:GetAttributeChangedSignal | RBXScriptSignal | Returns an event that fires when the given attribute changes. |
| Instance:GetAttributes | Dictionary | Returns a dictionary of the instance's attributes. |
| Instance:GetChildren | Instances | Returns an array containing all of the instance's children. |
| Instance:getChildren | Instances | |
| Instance:GetDebugId | string | Returns a coded string of the debug ID used internally by Roblox. |
| Instance:GetDescendants | Instances | Returns an array containing all of the descendants of the instance. |
| Instance:GetFullName | string | Returns a string describing the instance's ancestry. |
| Instance:GetStyled | Variant | Returns the styled or explicitly modified value of the specified property, or else the default property value if it hasn't been styled/modified. |
| Instance:GetStyledPropertyChangedSignal | RBXScriptSignal | Returns an event that fires when the given style property changes on the instance. |
| Instance:GetTags | Array | Gets an array of all tags applied to the instance. |
| Instance:HasTag | boolean | Check whether the instance has a given tag. |
| Instance:IsAncestorOf | boolean | Returns true if an Instance is an ancestor of the given descendant. |
| Instance:IsDescendantOf | boolean | Returns true if an Instance is a descendant of the given ancestor. |
| Instance:isDescendantOf | boolean | |
| Instance:IsPropertyModified | boolean | Returns true if the value stored in the specified property is not equal to the code-instantiated default. |
| Instance:QueryDescendants | Instances | Returns an array containing all descendants of the instance that match the selector string. |
| Instance:Remove | () | Sets the object's Parent to nil, and does the same for all its descendants. |
| Instance:remove | () | |
| Instance:RemoveTag | () | Removes a tag from the instance. |
| Instance:ResetPropertyToDefault | () | Resets a property to its default value. |
| Instance:SetAttribute | () | Sets the attribute with the given name to the given value. |
| Instance:WaitForChild | Instance | Returns the child of the Instance with the given name. If the child does not exist, it will yield the current thread until it does. |
Inherited from Object
| Name | Type / Returns | Description |
|---|---|---|
| Object:GetPropertyChangedSignal | RBXScriptSignal | Get an event that fires when a given property of the object changes. |
| Object:IsA | boolean | Returns true if an object's class matches or inherits from a given class. |
| Object:isA | boolean |
Events
Inherited from GuiBase2d
| Name | Type / Returns | Description |
|---|---|---|
| GuiBase2d.SelectionChanged | Fires when the gamepad selection moves to, leaves, or changes within the connected GuiBase2d or any descendant GuiObjects. |
Inherited from Instance
| Name | Type / Returns | Description |
|---|---|---|
| Instance.AncestryChanged | Fires when the Instance.Parent property of this object or one of its ancestors is changed. | |
| Instance.AttributeChanged | Fires whenever an attribute is changed on the Instance. | |
| Instance.ChildAdded | Fires after an object is parented to this Instance. | |
| Instance.childAdded | ||
| Instance.ChildRemoved | Fires after a child is removed from this Instance. | |
| Instance.DescendantAdded | Fires after a descendant is added to the Instance. | |
| Instance.DescendantRemoving | Fires immediately before a descendant of the Instance is removed. | |
| Instance.Destroying | Fires immediately before (or is deferred until after) the instance is destroyed via Instance:Destroy(). | |
| Instance.StyledPropertiesChanged | Fires whenever any style property is changed on the instance, including when a property is set to nil. |
Inherited from Object
| Name | Type / Returns | Description |
|---|---|---|
| Object.Changed | Fires immediately after a property of the object changes, with some limitations. |