← Back to course
medium ✦ 75 Studs

Clickable Buttons

Wire a TextButton's Activated event to run code when the player clicks it.

A ClickDetector lives on a 3D part out in the world. But lots of buttons should live on the player’s screen instead: a shop button, a “Claim Reward” button, a settings toggle. Those are GUI buttons, and the one you want is a TextButton.

You already built a ScreenGui with a TextLabel, so the setup feels familiar. A TextButton goes inside a ScreenGui (which lives in StarterGui so every player gets a copy on their screen). The difference from a label is right in the name: a button can be clicked, and it fires an event when it is.

Because GUI buttons live on the player’s own screen, you control them with a LocalScript, not a regular Script. A LocalScript runs on the player’s device, which is exactly where their screen and mouse are. Drop the LocalScript inside the ScreenGui and wire up the button:

local screenGui = script.Parent
local button = screenGui:WaitForChild("TextButton")
local label = screenGui:WaitForChild("TextLabel")

local clicks = 0

button.Activated:Connect(function()
  clicks = clicks + 1
  label.Text = "Clicked " .. clicks .. " times"
  button.BackgroundColor3 = Color3.fromRGB(0, 200, 120)
end)

The event to know is Activated. It fires when the player clicks or taps the button, and the nice thing about Activated is that it works for both mouse clicks AND touchscreen taps, so your button just works on phones too. (You may also see MouseButton1Click, which is the old mouse-only version. Activated is the friendlier, more modern pick.)

Look at what the click does: it reaches over and changes another part of the UI, the label.Text, plus the button’s own BackgroundColor3. That is the heart of every interactive interface. A button is just a trigger, and the real magic is what you change when it fires. Update text, swap a color, show or hide a frame, add Studs to a counter, all of it is “when this button is Activated, do that.”

One thing to keep straight: Activated does not hand you a player argument the way MouseClick did, because a LocalScript already knows whose screen it is on. If you need that player, you grab them with game.Players.LocalPlayer.

Now make it yours: build a button that visibly changes the screen, then push it further. Maybe the button toggles a shop frame open and closed, or each click flips the label between two messages. Once a screen button reliably runs your code, you have the last piece you need to build tycoon menus.

Build this in Roblox Studio, then check off each step: