How to detect a button click out of many buttons

So I have a team selection system and it works fine, but since all of the buttons do the same thing, exept they just different put you in a different team, I thought I could put them all in one script.

Spoiler Alert: I couldn’t.

The problem I’m having is that I don’t know how to check when any button is clicked out of a list of buttons, I know how to connect them all to one function, but not through one event. Is it even possible?

I searched and searched, but to no avail, it seems like the solution I’m looking for doesn’t exist yet

If you didn’t feel like reading all that, (which I don’t blame you, I wouldn’t) I’m just trying to find out how to detect for a button click out of many buttons with one event.

2 Likes

Make an event like ChangeTeam?

But actually changing the teams will require some coding, maybe lots.

(I apologize for the very short post.)

1 Like

I dont understand this question. Are you saying you want to make one script which detects if one of the buttons is clicked?

Keep All Your Buttons inside A Single Folder.
Add A RemoteEvent In Replicated Storage, Name it ChangeTeam

RENAME All Your Buttons to the Team Name,
Suppose If A Button Switches You to Red Team, Name it “Red” (Red Is your team name)

local FolderWithButtons = -- Define The Folder which Has ALL Buttons
local ClickDebounce = false

local function OnButtonCLICK(BUTTON)
   local Event = game.ReplicatedStorage.ChangeTeam
   Event:FireServer(BUTTON.Name)
end

for _, Button in pairs(FolderWithButtons) do 
   -- We Loop Through Each Button
   Button.Activated:Connect(function()
      if ClickDebounce==false then 
         ClickDebounce=true
         OnButtonCLICK(Button)
         wait(0.5)
         ClickDebounce=false
      end
   end)
end

Now on the Server Sided Code,

game.ReplicatedStorage.ChangeTeam.OnServerEvent:Connect(function(changer,teamname)
    changer.Team = game:GetService("Teams"):FindFirstChild(teamname)
end) 
2 Likes

Hey @Robenhood1416! I believe I know what you are getting at, however I think you may have a few terms mixed up so I will attempt to clarify and provide a solution.

First, I’ll go over the example of a single button’s Activated event connected to a single function:

--The named function approach
function onClick()
   print("Ouch, I was clicked")
end
[Button].Actiavted:Connect(onClick)

--The anonymous function approach
[Button].Actiavted:Connect(function()
   print("Ouch, I was clicked")
end)

The two examples above act exactly the same, however the first used a defined function named onClick and the second uses an anonymous function. In either case, the event of clicking the button ([Button].Activated) triggers a single function (either onClick or the anonymous function in the second example).

Every button has an event which you can connect a single function to using the :Connect() method of the event. (I’m assuming you’re using something like a TextButton or ImageButton here, but the concept still applies if you’re using something else too).

Often there are situation where multiple events should trigger the same function - although we may want the function to act slightly differently depending on the event that triggered it. Below is an example of how you might connect multiple buttons’ Actiavted event to the same function:
(This example assumes there are 3 buttons named “A”, “B”, and “C” inside a ScreenGui named “ScreenGui”)

local player = game.Players.LocalPlayer
local screenGui = player.PlayerGui.ScreenGui

function clicked(whichButton)
   if whichButton == screenGui.A then
      --The "A" button was clicked
   elseif whichButton == screenGui.B then
      --The "B" button was clicked
   elseif whichButton == screenGui.C then
      --The "C" button was clicked
   end
end

for _, button in ipairs({screenGui.A, screenGui.B, screenGui.C}) do
   --With each pass of this loop, `button` is a reference to the TextButton we
   -- are connecting the `Activated` event to
   button.Activated:Connect(function()
      clicked(button)
   end)
end

In this example the Activated event of each button (A, B, and C) is connected to a unique anonymous function which calls the clicked function passing as an argument a reference to the button that was clicked. The clicked function can then act differently depening on which button was clicked by comparing the argument it was passed.

@WheezWasTaken provided a similar and good answer on how to incorporate this into a RemoteEvent to let the server know which team the player selected, but I hope this post helped clarify how to connect multiple events to the same function.

2 Likes

So your response is closest to what I’m trying to do, but won’t the for loop run once? What if the player doesn’t click a button in that short time where the for loop is running?

I have multiple buttons and I want to connect them to one function, but through the same event.

My Solution Which i gave above, should work the same for all buttons and through one single event,
I Suggest you give it a try.

Also, the loop will run once, but since it consists of .Activated which is a function,
the function will run whenever we click the button, no matter how long has passed.

1 Like

Okay, I get it now, I’ll try it later today when I have time, Thank you.

1 Like

When you connect to an event using the :Connect() method, this connection persists until disconnected. (meaning that even after the loop has completed, the event connection is still active and will still trigger the function that it was bound to).

I don’t want to get overly complicated, but there are also other methods related to events, such as the :Disconnect() and :Wait() methods. Will include examples below in hidden sections if you’re curious:

Disconnect

In order to call :Disconnect() with purpose, you have to have first called :Connect(). Here’s an example that will disconnect a bound function after 5 seconds:

--(In a LocalScript inside a ScreenGui named "ScreenGui" with a TextButton child named "TextButton")
local clickConnection = script.Parent.TextButton.Activated:Connect(function()
   print("click")
end
task.wait(5) -- clickConnection will be active for 5 seconds
clickConnection:Disconnect()
--after the line above runs, the connection will be disconnected, so the function that prints "click"
--will no longer run when the button is clicked
Wait

Instead of connecting to an event indefinitely (aka if you want a function to run every time it is triggered, you can wait for the first time an event is triggered. The example below will only print “After” once the TextButton is clicked. After which it will no longer be connected.

--(In a LocalScript inside a ScreenGui named "ScreenGui" with a TextButton child named "TextButton")
print("Before")
script.Parent.TextButton.Activated:Wait()
print("After")

To emphasize where the code is at in execution, I included the “Before” and “After” print statements, which, if you test this yourself, you will notice that “Before” prints immediately, but “After” only prints once you have clicked the TextButton. This is because the :Wait() method of an event suspends execution of the Script or LocalScript until it is triggered.

1 Like

Thank you for your help, but since @East98 explained it better I had to mark his the solution