Roblox GUI Maker
← All guides

Scripting

How to Script a Roblox GUI (Clicks, Toggles & Tweens)

Building the frames is half of a Roblox GUI — the other half is scripting: making the close button actually close, the shop toggle open and shut, and the panel slide in instead of popping. This guide covers the four pieces of Luau that almost every GUI script needs: a LocalScript under StarterGui, a connected button, a visibility toggle, and a TweenService animation. Every snippet is complete and paste-ready.

Open the Settings template →

1. Where GUI scripts go: LocalScript under StarterGui

A GUI that each player sees for themselves is client-side. Put a LocalScript inside StarterGui (or inside the ScreenGui itself) and Roblox clones it into every player's PlayerGui when they join. Regular Scripts — the server kind — do not run inside PlayerGui.

If your GUI was built in Studio, the script can reach it through the player object. If you are creating the GUI from code instead, the script can build every Instance itself — the approach the exported code from this editor uses.

-- LocalScript under StarterGui
local player = game:GetService("Players").LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")

local screenGui = Instance.new("ScreenGui")
screenGui.Name = "SettingsGui"
screenGui.ResetOnSpawn = false
screenGui.Parent = playerGui
Tip: Set ResetOnSpawn = false on any menu or shop GUI, or it will disappear and rebuild every time the player respawns.

2. Connect a button click (the pattern behind every button)

Every interactive GUI element is wired the same way: get a reference to the instance, connect a function to its Activated event (works for mouse and touch), and do the work inside that function. Activated is preferred over MouseButton1Click because it also fires on mobile taps.

local button = screenGui:WaitForChild("Panel"):WaitForChild("CloseButton")

button.Activated:Connect(function()
    screenGui.Enabled = false
end)
Tip: If nothing happens when you click, print something inside the connect function. No output in the console means the path or the event name is wrong — nine times out of ten it is a typo'd Name in WaitForChild.

3. Toggle a GUI open and closed with one button

Shops and settings panels usually open from a HUD button and close from an X. The clean way is to flip ScreenGui.Enabled — when it is false, Roblox stops rendering the whole tree, so you get hiding for free.

local toggleButton = playerGui:WaitForChild("Hud"):WaitForChild("OpenShop")
local shopGui = playerGui:WaitForChild("ShopGui")

toggleButton.Activated:Connect(function()
    shopGui.Enabled = not shopGui.Enabled
end)

4. Animate the panel with TweenService

A GUI that fades or slides in feels dramatically more polished, and TweenService does it in a few lines. Create a Tween with a target property table, a time, and an easing style, then :Play() it. Position tweens interpolate UDim2 values directly.

local TweenService = game:GetService("TweenService")

local panel = screenGui:WaitForChild("Panel")
panel.AnchorPoint = Vector2.new(0.5, 0.5)
panel.Position = UDim2.fromScale(0.5, 0.6) -- start slightly low

local open = TweenService:Create(
    panel,
    TweenInfo.new(0.25, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
    { Position = UDim2.fromScale(0.5, 0.5) }
)

open:Play()
Tip: For a fade instead of a slide, tween a NumberValue and map it to GroupTransparency on a CanvasGroup — tweening TextTransparency per label is the slow path.

5. The one rule about client and server

Clicks happen on the client, but anything the game must enforce — currency, purchases, item grants, permissions — happens on the server. The pattern: the LocalScript fires a RemoteEvent, and a Script in ServerScriptService listens, validates, and applies the result.

If you can describe the change as purely visual (opening a panel, highlighting a tab), it can stay client-side forever.

6. Script it here, or script it there

The visual editor generates exactly this shape of code: a LocalScript that builds the hierarchy under a ScreenGui and wires Activated handlers for visibility actions, plus an optional server Script for Fire RemoteEvent actions. Build the layout visually, export, and read the generated Luau alongside this guide — the structure will match section for section.

Use this in your game

FAQ

Why won't my GUI button do anything when I click it?

Three usual causes: the script is a regular Script instead of a LocalScript (Scripts don't run in PlayerGui), the WaitForChild path doesn't match the actual Name of the button, or the connection was made before the instance existed. Add a print inside the handler to see which one it is.

Should I use MouseButton1Click or Activated?

Activated. It fires for mouse clicks and touch taps alike, while MouseButton1Click is mouse-oriented. Both live on GuiButton (TextButton, ImageButton).

How do I close a GUI when the player presses a key?

Connect UserInputService.InputBegan, check input.KeyCode, and flip ScreenGui.Enabled — the companion guide 'How to Open a GUI with a Key Press in Roblox' covers it with full code, including the gameProcessedEvent guard.

Can a LocalScript create the whole GUI from code?

Yes — Instance.new every element, set properties, and parent bottom-up. That is exactly what the Luau exported from this editor does, which keeps the GUI reproducible from one file.

Related guides

Skip the boilerplate

Everything in this guide — the hierarchy, the layout helpers, the button wiring — is built into the free Roblox GUI maker. Drag, drop, tweak real Roblox properties, then export clean Luau you can paste straight into Studio.