How to change something when a textbutton is clicked outside of starter gui

I want to make something happen when a text button is clicked, but it has to be outside of starter Gui. I’ve tried remote events, I don’t know what to do.

Can you please clarify what you mean by Outside of StarterGui?

Like workspace and serverscriptservice stuff like that

ScreenGui won’t display on the 3D parts so I’m assuming you want the buttons to display on where you want it to be in a PART you want, SurfaceGui can be your solution in that case but you’ll have to make the GUI in ScreenGui for suitable way first.

Also a reminder that SurfaceGui cannot be interacted by clients (mouse events won’t fire) if they’re parented to parts so you’ll have to put it in StarterGui and set Adornee to the parts you want before it initalizes to players, if you just want the button to float without sticking to the wall or parts then BillboardGUI is your secondary, acts like ScreenGUI and SurfaceGui but they float on any objects you set adornee to.

I want to change the music when a gui is hit, is that possible?

as long as it has RemoteEvents, you can change the sound id when client has fired an event, if you’re still stuck with implementing it, i’ve created an example game along with scripts incase you want to use it or view how things work, may look painful by the variable name but for beginners it’s atleast working and there’s a comment. :ok_hand:

--local script inside a SurfaceGui
local playerSV = game:GetService("Players")
local replicatclient = game:GetService("ReplicatedStorage")

local character = playerSV.LocalPlayer.Character

while character.Parent == nil do --wait for character to spawn, prevents client errors
	character.AncestryChanged:Wait()
end

local GUI = script.Parent --assign to SurfaceGui
local butonz = GUI.TextButton --assign from SurfaceGui to TextButton
local remote_srv = replicatclient.game_remote --get remote from ReplicatedStorage
local debounce = false

butonz.Activated:Connect(function() --list of events available [MouseButton1Down, MouseButton1Up, MouseButton1Click]
	print("Server is sending")
	
	if not debounce then --check if debounce is still false, re-activates after 
		debounce = true --sets debounce to true, This prevents over-firing remotes by macro and AutoClicker or server multiple fire
		remote_srv:FireServer() --tell server that a client has pressed
		butonz.BackgroundColor3 = Color3.fromRGB(255, 0, 0) --click inside a bracket to edit color
		
		task.wait(5) --set time you want
		
		debounce = false --re-activates after 30 seconds, Note that it's based on each client
		butonz.BackgroundColor3 = Color3.fromRGB(68, 255, 0)
	end
end)
local work_sc = game:GetService("Workspace") --kinda stupid to have this since you can just "workspace.Part" blahblah
local playerSV = game:GetService("Players")
local replicatclient = game:GetService("ReplicatedStorage")
local srv_storage = game:GetService("ServerStorage") --Because it is server-sided, we can get ServerStorage but not on LocalScript
local remote_srv = replicatclient.game_remote --get remote from ReplicatedStorage, can be accessible even if in ServerScriptService
local music_srv = work_sc.music_act --Where sounds play from workspace, it is replicated to all clients even if they're late
local isUsed = script.isUsed
local deb_ = false

local music_normal = srv_storage.music_normal:GetChildren() --gets all the sound contained in folder
local music_act = srv_storage.music_snd:GetChildren() --gets all the sound contained in folder

local music_normal_rand = music_normal[math.random(1, #music_normal)] --randomizes a sound by LuaU VM

remote_srv.OnServerEvent:Connect(function(plyr_crv) --The first argument is a player, can be useless in some scenario
	music_normal_rand:Stop() --stop the normal 
	if not deb_ then
		deb_ = true
		
		local music_act_rand = music_act[math.random(1, #music_act)] --randomizes a sound by LuaU VM
		music_srv.SoundId = music_act_rand.SoundId --set the SoundId picked by music_act_rand
		music_srv:Play() --Play the sound
		print("Ready!")
		
		isUsed.Value = true --Set value to true
		task.wait(30)
		
		isUsed.Value = false --Set value to false, tells the "Changed" event that it has ended
		music_srv:Stop()
		deb_ = false
	else
		warn("Cannot be Commanded, Wait for the game server")
	end
	
	
end)

isUsed.Changed:Connect(function(bool) --event to call when bool value has changed
	if bool == false then 
		print("Ended, Going back to normal")
		
		local music_normal_rand = music_normal[math.random(1, #music_normal)] --randomizes a sound by LuaU VM, This is inside a scope so it doesn't assign outside
		music_srv.SoundId = music_normal_rand.SoundId --set the SoundId picked by music_act_rand
		task.wait(0.02)
		music_srv:Play()
	end
end)

music_srv.SoundId = music_normal_rand.SoundId --set the SoundId picked by music_act_rand
music_srv:Play() --plays once first client started the server

button_music_example.rbxl (63.8 KB)