ScreenGui not working serverside through the use of a screen button

I am having a problem trying to get a ScreenGUI to show to all players from the click of a clientside GUI (Only 1 person has access to the button). The Gui is meant to be a series of messages that pop up on a user’s screen once the button is clicked. I have provided all associated codes below. Please note that I have tried multiple different scripting techniques to get it to work.

The GUIs show up fine clientside but are virtually non-existent to anyone else.

The audio is serverside, however, and everyone can hear the audio.

Please note: I am using RemoteEvents, activated from a LocalScript (a child of the button), and the command is used in a ServerScript. I used this technique with a jump disabling system, but it isn’t seeming to work for the GUIs.

LocalScript (Child of the ClientSide GUI TextButton)

function onClick()
	game.Workspace.ControlPanelTest.cruiseannc:FireServer()
end

script.Parent.MouseButton1Down:Connect(onClick)

ServerScript (With the command)

local Players = game:GetService("Players")

game.Workspace.ControlPanelTest.cruiseannc.OnServerEvent:Connect(function(Player)
	game.Workspace.ControlPanelTest.AudioBlock.DingDong.Playing = true
	Player:WaitForChild('PlayerGui'):WaitForChild('Cruising').Frame1.Visible = true
	wait(4)
	Player:WaitForChild('PlayerGui'):WaitForChild('Cruising').Frame1.Visible = false
	Player:WaitForChild('PlayerGui'):WaitForChild('Cruising').Frame2.Visible = true
	wait(7)
	Player:WaitForChild('PlayerGui'):WaitForChild('Cruising').Frame2.Visible = false
	Player:WaitForChild('PlayerGui'):WaitForChild('Cruising').Frame3.Visible = true
	wait(9)
	Player:WaitForChild('PlayerGui'):WaitForChild('Cruising').Frame3.Visible = false
	Player:WaitForChild('PlayerGui'):WaitForChild('Cruising').Frame4.Visible = true
end)

ServerScript (A different technique)

local Players = game:GetService("Players")

game.Workspace.ControlPanelTest.cruiseannc.OnServerEvent:Connect(function(plr)
	game.Workspace.ControlPanelTest.AudioBlock.DingDong.Playing = true
	plr.PlayerGui.Cruising.Frame1.Visible = true
	wait(4)
	plr.PlayerGui.Cruising.Frame1.Visible = false
	plr.PlayerGui.Cruising.Frame2.Visible = true
	wait(7)
	plr.PlayerGui.Cruising.Frame2.Visible = false
	plr.PlayerGui.Cruising.Frame3.Visible = true
	wait(9)
	plr.PlayerGui.Cruising.Frame3.Visible = false
	plr.PlayerGui.Cruising.Frame4.Visible = true
end)

Please note: I tried multiple other ways of doing it, but could not get it to work serverside. I am a relative amateur at scripting, so any help is appreciated.

The goal is to get the GUI to appear on all player’s screens at the activation of the button, rather than clientside to the person activating said button.

First off, ALL RemoteEvents/RemoteFunctions should be under ReplicatedStorage. With that in mind, when you change it, try this:

LocalScript:

function onClick()
    game.ReplicatedStorage.ControlPanelTest.cruiseannc:FireServer()
end

script.Parent.MouseButton1Down:Connect(onClick)

ServerScript:

local Players = game.Players:GetPlayers()

game.ReplicatedStorage:FindFirstChild("cruiseannc", true).OnServerEvent:Connect(function()
    for i = 1, #Players do
        local CurrentPlayer = Players[i]
        local PlayerGui = CurrentPlayer.PlayerGui
        local Cruising = PlayerGui:FindFirstChild("Cruising")

        Cruising.Frame1.Visible = true
        task.wait(4)
        Cruising.Frame1.Visible = false
        Cruising.Frame2.Visible = true
        task.wait(7)
        Cruising.Frame2.Visible = false
        Cruising.Frame3.Visible = true
        task.wait(9)
        Cruising.Frame3.Visible = false
        Cruising.Frame4.Visible = true
    end
end)

Merry Christmas! :santa:

2 Likes

I think for what your asking u would need to do the fireallclients from a remote event and then change the visiblity client side

2 Likes

That’s another way, however that has to be from a ServerScript to a LocalScript. In this instance, it needs to be a LocalScript to ServerScript, to access all client data.

2 Likes

This would be a big plus to make the client listen for the same remote event and perform their own logic when the server fires. Right now, it looks like the server would be yielding to perform all this for each client

1 Like

Yea thats why I said about it. It also makes it a little more efficient as it happen all at the same time unlike the looping through the players which do one by one which could be slower but at the same time probs would not affect this much.

1 Like

Once again, my script is Server-sided. You can’t access every client’s PlayerGui from one client’s script. FireAllClients is meant for Server-to-client communication, which is why we need to loop through every player and do it that way. Fun fact: Loops can run for everyone in 0.01 seconds if it doesn’t have a wait, so it isn’t a big deal.

1 Like

Just tried this! No luck, and for some reason, there is no error in Output linked to it.

Interesting. Once again, make sure the RemoteEvent (cruiseannc) is in ReplicatedStorage! It doesn’t matter where, because where the script looks for it is recursive, meaning it will check everywhere until it finds it.

The RemoteEvent is under ReplicatedStorage. I’m also going to attach a few other pictures that may help you understand how everything is lined up a bit better.
image

(The highlighted script is the script in question, the additional scripts apply to the other controls, which all work as expected)
image

Again, it would be too much to put here, but there is no Output errors linked to it, so I’m not quite sure where it’s going wrong. Again, I’m a relative amateur catching on pretty quick, haha.

Thanks again for your help and Merry Christmas! :santa:

Awh, unfortunately, I don’t have a solution then. I hope you are able to fix this issue! Thank you for your time! :slight_smile:

You can’t access every client’s PlayerGui from one client’s script. FireAllClients is meant for Server-to-client communication, which is why we need to loop through every player and do it that way.

I’m not sure what the standpoint here is, FireAllClients wouldn’t need iteration through each player. There’d be no need I can see for client-to-client referencing GUI’s here from what I can tell by what OP is trying to achieve. What @LifeDigger and I were suggesting is something structured like this (don’t have studio on hand so forgive me if I write an error):

Localscript

local function onClick()
	game.ReplicatedStorage.ControlPanelTest.cruiseannc:FireServer()
end

local function onAnnc()
	local Cruising = game:GetService("Players").LocalPlayer.PlayerGui:FindFirstChild("Cruising")

	Cruising.Frame1.Visible = true
	wait(4)
	Cruising.Frame1.Visible = false
	Cruising.Frame2.Visible = true
	wait(7)
	Cruising.Frame2.Visible = false
	Cruising.Frame3.Visible = true
	wait(9)
	Cruising.Frame3.Visible = false
	Cruising.Frame4.Visible = true
end

game.ReplicatedStorage.ControlPanelTest.cruiseannc.OnClientEvent:Connect(onAnnc)
script.Parent.MouseButton1Down:Connect(onClick)

Server script:

game.ReplicatedStorage.ControlPanelTest.cruiseannc.OnServerEvent:Connect(function(Player)
        game.Workspace.ControlPanelTest.AudioBlock.DingDong.Playing = true
	game.ReplicatedStorage.ControlPanelTest.cruiseannc:FireAllClients()
end)

*Edited to add the sound back to the server script

1 Like

What would the placement be for these scripts? I currently have the LocalScript as a child of the button and the ServerScript just placed in the models. Would it remain this way?

Ideally the server script goes into ServerScriptService so it’s not replicated to the clients. LocalScript would stay the same

This also has no output errors but the GUI still doesn’t want to show.

The only output error is that there is, is that there is no ‘ControlPanelTest’ in ReplicatedStorage. When I deleted ControlPanelTest to make it look directly for the RemoteEvent no additional errors showed up.

Let’s add some debug statements and more explicit references to see where it’s going wrong:
Server script:

local cruiseAnnc = game:GetService("ReplicatedStorage"):WaitForChild("cruiseannc")

cruiseAnnc.OnServerEvent:Connect(function(ply)
	print(ply.Name .. " has requested an announcement. Playing sound:")
	game.Workspace.ControlPanelTest.AudioBlock.DingDong.Playing = true
	print("Firing the event to all the clients:")
	cruiseAnnc:FireAllClients(ply.Name)
end)

Local script:

local ply = game:GetService("Players").LocalPlayer
local cruiseAnnc = game:GetService("ReplicatedStorage"):WaitForChild("cruiseannc")

local function onClick()
	print("Button clicked, firing at the server...")
	cruiseAnnc:FireServer()
end

local function onAnnc(name)
	print("Received an announcement from " .. name)
	
	local Cruising = ply.PlayerGui:FindFirstChild("Cruising")
	
	if Cruising then
		print("Found the Cruising frame")
		Cruising.Frame1.Visible = true
		wait(4)
		Cruising.Frame1.Visible = false
		Cruising.Frame2.Visible = true
		wait(7)
		Cruising.Frame2.Visible = false
		Cruising.Frame3.Visible = true
		wait(9)
		Cruising.Frame3.Visible = false
		Cruising.Frame4.Visible = true
		print("Finished!")
	else
		print("Cruising frame not found! :(")
	end
end

cruiseAnnc.OnClientEvent:Connect(onAnnc)
script.Parent.MouseButton1Down:Connect(onClick)

*Edit, forgot to reference the event on client the same way

Weird, this worked! Give me just a second so that I can find someone to join me and make sure it works serverside.

1 Like

You can also test multiple players in Studio by going to the “Test” tab, and under the banner for Clients and Servers, select how many players to emulate and hit Start.

Cool, learn something new everyday. Nope, still clientsided :confused:

How far along do the debug statements go? Does it get to the “Found cruising” part, or does the event not happen at all?