Destroying a GUI for all players on server-sided script

Hey! :wave:

I’m trying to destroy an element of a GUI for all players when one player clicks it. The name of the GUI is referenced as the ‘guiName’ parameter using the remoteevent. Unfortunately, the current script I have is not working. If anyone can help me figure this out, it’d be appreciated! :heart:

Script:

game.ReplicatedStorage.LogAnsweredPTS.OnServerEvent:Connect(function(player, guiName)
	for _, player in pairs(duplrs:GetPlayers()) do
			player.PlayerGui[guiName]:Destroy()
	end
end)

NOTE: The name of the GUI is the username of the player who triggered the remoteevent, meaning it always changed based on which player triggered it.

Thank you to everyone who tries to assist me with this.

3 Likes

The proper way afaik is to have a remote event with LocalScript’s listening to the remote, and having the server fire the remote when it wants to remove/hide all the guis.

image

-- ServerScriptService.Script
game.ReplicatedStorage.Events.HideGui:FireAllClients()
-- StarterGui.Gui.LocalScript
game.ReplicatedStorage.Events.HideGui.OnClientEvent:Connect(function()
	script.Parent:Destroy()
end)

Additional suggestions:

  • Instead of destroying the GUI, simply change its .Enabled property.
  • OnHide event should be changed to something more general, like GuiEnabledStateChanged

This won’t work, because there are multiple of the exact SAME gui elements and I need to reference them using the name. If I put this under the GUI element that gets cloned, it will destroy all of them. If this doesn’t make sense, let me know.

Localscript:

    local player = game.Players.LocalPlayer
    local groupid = 7331168
game.ReplicatedStorage.PTSRequestGrant.OnClientEvent:Connect(function(PTSName)
    if player:GetRankInGroup(groupid) >= 10 then
    local frameclone = player.PlayerGui.PTSDisplayer.HolderFrame.SampleFrame:Clone()
    frameclone.Parent = script.Parent.HolderFrame
    frameclone.Visible = true
    frameclone.Text = PTSName.." has requested PTS!"
    frameclone.Name = PTSName
    end
    end)

Other localscript that fires the remoteevent:

local player = game.Players.LocalPlayer
local answered = false

script.Parent.MouseButton1Click:Connect(function()
	local name = script.Parent.Name
	if answered == false then
		game.ReplicatedStorage.LogAnsweredPTS:FireServer(name)
		answered = true
	end
end)

EDIT: I tried your script, it worked however it destroyed all of the cloned GUI elements rather than just the 1.

Also, it’s not the GUI that I want to destroy, it’s just a certain frame on a GUI.

That was just an example of how you would delete gui’s of players from the server.
If you want to delete a specific gui:

-- LocalScript is child of GUI (not suggested)
OnServerEvent:Connect(function(guiName)
   if script.Parent.Name == guiname then
      script.Parent:Destroy()
   end
end)
-- LocalScript is child of StarterPlayerScripts (also not recommended but sort of better??)
OnServerEvent:Connect(function(guiName)
    local gui = LocalPlayer.PlayerGui:FindFirstChild(guiName)
    if gui.ClassName == "ScreenGui" then
        gui:Destroy()
    end
end)

I don’t suggest you have multiple of the same guis with the only difference being players. If you provided more context to exactly what LogAnsweredPTS is supposed to do, I could come up with a better solution.

Maybe take time to actually learn instead of creating multiple posts hoping someone will give you something to paste…

anyways here’s something to paste:

game.ReplicatedStorage:WaitForChild("LogAnsweredPTS").OnServerEvent:Connect(function(player, guiName)
	for _, player in pairs(duplrs:GetPlayers()) do
		local Gui = player.PlayerGui:FindFirstChild(guiName)
		if Gui then
			Gui:Destroy()
		end
	end
end)

This doesn’t work for some reason, full script below.

game.ReplicatedStorage.LogAnsweredPTS.OnServerEvent:Connect(function(player, guiName)
	local duplrs = game:GetService("Players")
	local getplr = game.Players[guiName]
	local http = game:GetService("HttpService")
	local Data = {
		["content"] = "**"..player.Name.."** has answered **"..guiName.."**'s PTS request! :tada:"
	}
	Data = http:JSONEncode(Data)
	http:PostAsync("apilinkhere", Data)
	local PlayerHumanoid = player.Character:WaitForChild("Humanoid")
	local TargetHumanoid = getplr.Character:WaitForChild("Humanoid")

	local LastTargetPosition = TargetHumanoid.RootPart.CFrame
	local Length = 3 -- Length between player and target player

	PlayerHumanoid.RootPart.CFrame = LastTargetPosition + LastTargetPosition.LookVector * Length
	PlayerHumanoid.RootPart.CFrame = CFrame.new(PlayerHumanoid.RootPart.CFrame.Position, Vector3.new(LastTargetPosition.Position.X, PlayerHumanoid.RootPart.CFrame.Position.Y, LastTargetPosition.Position.Z))
	for _, player in pairs(duplrs:GetPlayers()) do
		local StartGui = player.PlayerGui:WaitForChild("PTSDisplayer")
		local HolderFrame = StartGui:WaitForChild("HolderFrame")
		local Gui = HolderFrame:FindFirstChild(guiName)
		if Gui then
			Gui:Destroy()
		end
	end
end)

You cant do :onserverevent in a localscript. The remoteevent does everything the script I sent in my last post says.

This depends on where the Gui was created. If it was done on the server, you can simply use this line of code:

local Players = game:GetService("Players")
local NameOfGui = "ScreenGui"


for _, v in ipairs(Players:GetPlayers()) do
  local findGui = v.PlayerGui:FindFirstChild(NameOfGui)
  if findGui then findGui:Destroy() end
end

Otherwise, you’ll have to set up some sort of RemoteEvent bridge to tell each client to delete said Gui.

ps clients listen to RemoteEvent.OnClientEvent

It’s not an actual ScreenGUI, it’s a frame inside of a screengui.
image

Ok then, use your local script to listen to a RemoteEvent in ReplicatedStorage, in this example I’ll call it DeletePlayerGui

Next, in your local script, set up a listener doing the following:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

ReplicatedStorage.DeletePlayerGui.OnClientEvent:Connect(function()
  --code to delete frame
end)

Now, if you call FireAllClients on that remote in a server script, the frame will be destroyed

Again, there are multiple of the same GUI elements and doing this will delete them all. As you can see in the screenshot above, the ‘SampleFrame’ TextButton gets cloned and named as the player who triggered the events’ username, so I need to be able to find a working way to reference the name of it in a script where I can destroy it.

FireAllClients can take a variadic amount of arguments which is then passed to your listeners which means its possible to add a filter to your system

RemoteEvent:FireAllClients("Hello World")

RemoteEvent.OnClientEvent:Connect(print) --> "Hello World" (this is the same as function(arg) print(arg) end)

So would game.ReplicatedStorage.LogAnsweredPTS:FireAllClients(guiName) pass the GUI name through from a serverscript to a localscript?

Also, would this work?

This is the correct way to pass arguments through a remote event and have it handled on the client.

How would I check if the name is correct?

Would this work?

game.ReplicatedStorage.LogAnsweredPTS.OnClientEvent:Connect(function(nameofgui)
	if script.Parent.Name == nameofgui then
		script.Parent:Destroy()
	end
end)

we need reactions the forum

Yes it would.

1 Like

This works, thank you so much for your help!