Getting player who clicks surface GUI button

I need to get the player who clicked a SurfaceGUI button on the server.

The buttons are procedurally generated during runtime so I can’t just have the GUI in StarterGUI and set the adornee to the part.

2 Likes

You can use a RemoteEvent or RemoteFunction to send data across the client-server boundary.

Does this procedural generation add anything to a Folder? You can try listening for the ChildAdded of something and check if it’s a SurfaceGui using the :IsA() method.

If that SurfaceGui is detected, then you can simply reference the button within it and listen for a .MouseButton1Click signal. There is no way to detect the recipient (person who pressed an ImageButton or TextButton) from a server script, so you’ll have to detect it on the client.

-- In a local script,
local Something = nil -- I don't know how your procedural generation works, but I think children get added into Workspace. You can listen for that.

local remote_event = nil

local Players = game:GetService("Players")
local Player = Players.LocalPlayer


Something.ChildAdded:Connect(function(Child: Instance)
    if Child:IsA("SurfaceGui") then
        local button = nil -- Button
        button.MouseButton1Click:Connect(function()
            remote_event:FireServer(...) -- This method passes in the player as a default argument. You can pick it up on the server.
            -- If the player will only be pressing the button once, then use the :Once() method to connect to a function. The signal will disconnect itself after the player has pressed the button.
        end)
    end
end)
-- In a server script,
local remote_event: RemoteEvent = nil

remote_event.OnServerEvent:Connect(function(player: Player)
    print(player.Name .. " has pressed a button.")
end)
1 Like

That’s incorrect. Using a ClickDetector, there is a parameter to get the player from the server side. I’d recommend instead of using a surfacegui, use a TextLabel with a ClickDetector on a separate part that is aimed in the center of the textlabel.

1 Like

I was talking about a TextButton or ImageButton. I should’ve specified, sorry!

1 Like

In that case you can do what astrovue said, or else you could try this, though I doubt its reliability.

game.Players.PlayerAdded:Connect(function(plr)
   plr.PlayerGui.ScreenGui.TextButton.Activated:Connect(function()
      print(plr..' activated smth')
   end)
end)

Try this:

  1. Add a RemoteEvent inside of ReplicatedStorage
  2. Add a server Script as a direct child of the SurfaceGUI button, and set the script’s RunContext to Client (this will allow it to run client-sided as a descendant of Workspace). This will be the code:
-- Server Script with RunContext set to Client
-- Needs to be a direct child of the GUI button
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local button = script.Parent
local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")


button.Activated:Connect(function()
	remoteEvent:FireServer()
end)
  1. Add a server Script in ServerScriptService, which will listen for when the RemoteEvent is fired:
-- Server Script in ServerScriptService
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remoteEvent = ReplicatedStorage.RemoteEvent


remoteEvent.OnServerEvent:Connect(function(player: Player)
	print(`Player {player.UserId} ({player.DisplayName}) has clicked the GUI button`)
end)

I found a way to do it with workspace.DescendantAdded but what JohhnyLegoKing said would probably work. I didn’t even think about a server script set to run on the client.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.