The Fundamentals of Scripting with GUIs

UDim2[edit]

Main article: UDim2

The system of GUI sizing and positioning is very different from Vector3 which is used to position parts. The UDim2.new function accepts four arguments. The arguments for UDim2.new are xScale, xOffset, yScale, and yOffset. xScale and yScale will return values relative to the size of their parent. If a GUI's parent has a width of 100, setting xScale to 0.5 will return 50 while setting xScale to 1 will return 100. The same goes for height and yScale. xOffset is the number of pixels added to whatever is returned by xScale. For example if the parent width is 100, xScale is 0.5, and xOffset is 25, 75 will be returned (100*0.5 + 25). The same goes for yOffset and yScale.

local frame = Instance.new("Frame")
frame.Position = UDim2.new(0.25, 0, 0.25, 0)
frame.Size = UDim2.new(0.5, 0, 0.5, 0)

This will create a rectangular GUI that is positioned in the middle of the display and covers 25% of the screen (half width and half height).

Note: The XY grid that these 2D Guis use is different from the coordinates the rest of ROBLOX uses. The (0, 0) position is in the upper left corner of a GUI element. In this grid right is positive in the X direction and down is positive in the Y direction.

GUI Types[edit]

In ROBLOX all GUI's have to be inside of a special container. There are three different types of container for displaying a GUI: ScreenGui, SurfaceGui, and BillboardGui: GuiTypes.png

ScreenGui[edit]

A ScreenGui is drawn directly to the player's screen (does not have a position in the game world). This is commonly used for HUDs, minimaps, any information or graphics that need to travel with the player. Elements in a ScreenGui are only visible to the player that owns it. To add a ScreenGui into a game it can either be put into StarterGui which will copy it to every new player who joins the game, or can be put directly into a player's PlayerGui, in which case it would only be visible to that player.

SurfaceGui[edit]

A SurfaceGui is drawn on the surface of a Part. This will stick to the part, even if the part moves or rotates. To add a SurfaceGui to a game it can be put directly into the Part that you want it to draw on (which will display the GUI for all players). Alternatively, the SurfaceGui can be put into a StarterGui which will copy it to every new player who joins the game, or can be put directly into a player's PlayerGui, in which case it would only be visible to that player. If the SurfaceGui is put into StarterGui or PlayerGui, the Adornee must be set to the part where you want the Gui to display.

BillboardGui[edit]

A BillboardGui is drawn at the position of a Part but will always face the player. If the part moves the BillboardGui will move with it. If the size of the BillboardGui is set using only the Scale components of it's API:Class/BillboardGui/Size UDim2 then it will scale based on distance to the player (i.e. it will get bigger as the player gets closer, will get smaller as the player goes farther). If the Offset of the Size is set then the BillboardGui will maintain the same size regardless of distance to the player.

A BillboardGui can be put directly into the Part that you want it to draw over (which will display the GUI for all players).Alternatively, the BillboardGui can be put into a StarterGui which will copy it to every new player who joins the game, or can be put directly into a player's PlayerGui, in which case it would only be visible to that player. If the BillboardGui is put into StarterGui or PlayerGui, the Adornee must be set to the part where you want the Gui to display.

GUI Objects[edit]

There are several GUI objects that allow you to create user interfaces, but all GUI objects have to go inside a container (see #GuiTypes)

Frame[edit]

A Frame object is the simplest of the GUI objects. Creating a Frame makes a box with a background color and border color. When an object is parented under a Frame, the object's position will be relative to the position of the parenting Frame.

Select
-- In a LocalScript in StarterGui:
 
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = script.Parent
 
-- Create Frame
local frame = Instance.new("Frame")
frame.Parent = screenGui
frame.Position = UDim2.new(0, 25, 0, 25)
frame.Size = UDim2.new(0, 100, 0, 50)

FrameExample.png

ScrollingFrame[edit]

A ScrollingFrame is similar to a Frame but it can be larger than what is drawn to the screen. If this is the case, then scroll bars will appear on the sides which the player can drag to reveal the rest of the ScrollingFrame.

ScrollingFrameExample.gif

For more on ScrollingFrames see this Tutorial.

Labels[edit]

Labels are used to display static things. There are currently two types of labels: TextLabel and ImageLabel.

TextLabel[edit]

A TextLabel is similar to a Frame except that it can display text.

Select
-- In a LocalScript in StarterGui:
 
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = script.Parent
 
-- Create TextLabel
local textLabel = Instance.new("TextLabel")
textLabel.Parent = screenGui
textLabel.Position = UDim2.new(0, 25, 0, 50)
textLabel.Size = UDim2.new(0, 150, 0, 50)
textLabel.BackgroundColor3 = BrickColor.White().Color
textLabel.Text = "Hello ROBLOX!"

TextLabelExample.png

ImageLabel[edit]

A ImageLabel displays an image (which needs to be uploaded to ROBLOX as a Decal).

Select
-- In a LocalScript in StarterGui:
 
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = script.Parent
 
-- Create ImageLabel
local imageLabel = Instance.new("ImageLabel")
imageLabel.Parent = screenGui
imageLabel.Position = UDim2.new(0, 25, 0, 50)
imageLabel.Size = UDim2.new(0, 100, 0, 100)
imageLabel.Image = "rbxassetid://133293265"

ImageLabelExample.png

Buttons[edit]

Buttons are similar to Labels in how they are displayed but add several events to handle Mouse input. Note that the events must defined in a LocalScript as the server does not know about player input.

TextButton[edit]

A TextButton displays the same as a TextLabel except that it adds more Mouse events.

Select
-- In a LocalScript in StarterGui:
 
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = script.Parent
 
-- Create TextButton
local textButton = Instance.new("TextButton")
textButton.Parent = screenGui
textButton.Position = UDim2.new(0, 25, 0, 50)
textButton.Size = UDim2.new(0, 150, 0, 50)
textButton.BackgroundColor3 = BrickColor.White().Color
textButton.Text = "Click Me!"
 
-- Bind function to button click
textButton.MouseButton1Down:connect(function()
	textButton.Text = "I've been clicked!"
end)

TextButtonExample.gif

ImageButton[edit]

A ImageButton displays the same as a ImageButton except that it adds more Mouse events.

Select
-- In a LocalScript in StarterGui:
 
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = script.Parent
 
-- Create ImageButton
local imageButton = Instance.new("ImageButton")
imageButton.Parent = screenGui
imageButton.Position = UDim2.new(0, 25, 0, 50)
imageButton.Size = UDim2.new(0, 100, 0, 100)
imageButton.Image = "rbxassetid://133293265"
 
-- Create TextLabel to show after button click
local text = Instance.new("TextLabel")
text.Parent = screenGui
text.Position = UDim2.new(0, 25, 0, 50)
text.Size = UDim2.new(0, 100, 0, 100)
text.Text = "I've been clicked!"
text.BackgroundTransparency = 1
text.Visible = false
 
-- Bind function to button click
imageButton.MouseButton1Click:connect(function()
	text.Visible = true
end)

ImageButtonExample.gif

TextBox[edit]

A TextBox displays the same as a TextLabel except that it allows for a user to enter custom text.

Select
-- In a LocalScript in StarterGui:
 
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = script.Parent
 
-- Create TextBox
local textBox = Instance.new("TextBox")
textBox.Parent = screenGui
textBox.Position = UDim2.new(0, 25, 0, 50)
textBox.Size = UDim2.new(0, 150, 0, 50)
textBox.BackgroundColor3 = BrickColor.White().Color
textBox.Text = "Type here"

TextBoxExample.gif

Manipulating GUIs[edit]

Positioning an element[edit]

You can use code to position an element on someone's screen based on a numeric value, or based on a ratio on their screen. To position an element at the point (100,100), you would use the folowing code.

element.Position = UDim2.new(0, 100, 0, 100)

Note that the first and third arguments are Scale and not Offset. Offset is what you want to use if you are thinking of pixels. Using Offset will not generate a difference between computer screens.

If you wanted to position an element by "screens" not "pixels" (like, put an element a quarter of a "screen" to the left and down), you would use scale.

element.Position = UDim2.new(0.25, 0, 0.25, 0)

Note that using scale will generate a difference between computer screens. If your screen is large, then the look will be different than a small computer screen. If you wanted to position something in the center of the screen, then use this code to say "I want one-half screens on X and Y, then go down by 50 pixels". This is similar to the positioning of the speed indicator on a VehicleSeat.

element.Position = UDim2.new(0.5, 0, 0.5, -50)

Also note that positioning an element moves it relative to it's parent container. For example, suppose a game had a TextLabel inside of a Frame, which itself was inside a ScreenGui. Changing the Position of the TextLabel would move it relative to the Frame (0,0 in this case would be the upper left corner of the Frame), while changing the Position of the Frame would move both it and the TextLabel relative to the ScreenGui.

Resizing an element[edit]

To change the size of a GUI element use the Size property. For example If you wanted something half the width of its parent:

element.Size = UDim2.new(0.5, 0, 0.5, 0)

You can even make an element cover the entirety of its parent (if the parent is a ScreenGui then the element would cover the entire screen). To do this set the scale of the Size in both X and Y to 1:

element.Size = UDim2.new(1, 0, 1, 0)

Sometimes using scale for a GUI element is not appropriate. For example, if you are using ImageLabel the image could be distorted if it is stretched too much. In this case consider using just the offset component of the Size:

element.Size = UDim2.new(0, 64, 0, 64)

Adding motion to an element[edit]

GUI elements do not have to remain static, they can be moved while a game is running. For example, suppose you want to have text scroll across the top of the player's screen. This can easily be done by changing the Position of the element relative to it's current position. The following code, when in a LocalScript in StarterGui will make a TextBox scroll across the top of a player's screen:

Select
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = game.Players.LocalPlayer.PlayerGui
local textLabel = Instance.new("TextLabel")
textLabel.Parent = screenGui
textLabel.Text = "Hello " .. game.Players.LocalPlayer.Name
textLabel.Size = UDim2.new(0, 100, 0, 30)
 
local xPosition = 1
local speed = 0.0025
while true do
	xPosition = xPosition - speed
	textLabel.Position = UDim2.new(xPosition, 0, 0, 0)
	if xPosition < -0.1 then
		xPosition = 1
	end
	wait()
end

Notice that the xScale component of the TextLabel's Position is never set explicitly to a number. Instead we are using a variable which is changing over time.

GUIMotionExample.gif

For more advance animation and movement techniques, see Tweening.

Input[edit]

GUI's are not just for displaying things to the player. They can also be a source of input. The most obvious case is with the Button type of GUI element (TextButtons and ImageButtons). To handle a mouse event on a button, one has to connect a function to the event in a LocalScript. Consider the following LocalScript when it is put into StarterGui:

Select
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = game.Players.LocalPlayer.PlayerGui
local textButton = Instance.new("TextButton")
textButton.Size = UDim2.new(0, 100, 0, 100)
textButton.Parent = screenGui
textButton.MouseButton1Down:connect(function()
	print("clicked")
	-- More code to handle the click event can go here
end)

This script will create a ScreenGui and put a TextButton into it. It then binds a function to the MouseButton1Down event of the button. Any code we want to run when the button is clicked can be put into this function. Note that this exact code will also work for ImageButtons as well (just replace "TextButton" with "ImageButton" in the Instance.new call).

There are many functions that fire in GUI elements, even in the simpler ones such as Frame. For a complete list, see Events in GuiObject. Buttons such as TextButton and ImageButton also have a few more events, all of which can be seen under Events in GuiButton.

Practice[edit]

Exercise 1

Instructions

Make an button in ScreenGUI that resets (kills) the character when clicked. Feel free to use an image if you want!

Solution
Select
-- In a LocalScript in StarterGui:
 
-- Create ScreenGui
local screenGui = Instance.new("ScreenGui")
screenGui.Parent = script.Parent
 
-- Create TextButton
local textButton = Instance.new("TextButton")
textButton.Parent = screenGui
textButton.Position = UDim2.new(0, 50, 0, 50)
textButton.Size = UDim2.new(0, 140, 0, 60)
textButton.TextColor3 = BrickColor.White().Color
textButton.Style = 2
textButton.Text = "Reset Character"
 
-- Bind function to button click
textButton.MouseButton1Down:connect(function()
	game.Players.LocalPlayer.Character.Humanoid.Health = 0
end)


Exercise 2

Instructions

Make a desk with a name tag that displays your name with a TextLabel in a Surface GUI

Solution
Select
--Scripting was not necessary for this exercise.  A link to the solution is included below:
--http://web.roblox.com/Desk-with-Customizable-Nametag-item?id=166354648