I want one script to be able to detect MouseButton1Down events of multiple buttons that do not exist before runtime. I understand that one script may have several connections to pre-existing buttons, but that is not what I’m looking for. I want the script to, in real time, find all buttons under the GUI and connect a function to their MouseButton1Down events. Currently, I have one script that is Cloned and placed inside the button such that each button has its own script. However, I feel that this is inefficient because there are extensive amounts of the same, copied script throughout my GUI.
For reference, this is the code of my current script:
script.Parent.MouseButton1Down:Connect(function()
if script.Parent.Name == "SellButton" then
--do stuff
elseif script.Parent.Name == "BuyButton" then
--do stuff
end
end)
An example of this use is my custom leaderboard. As players join, there are additional buttons that weren’t there before runtime, and now I want the game to recognize and act on their events without cloning a script into the buttons. How may I go about a more efficient method?
Yes, you definitely want to have just one script doing this. Have a script directly parented to the Gui object and use WaitForChild() to pause the script and wait for each of the buttons to load in.
Then just used the Descendant added event to the screen gui and check if its a button then set up the connection:
local ScreenGui = --insert here
ScreenGui.DescendantAdded:Connect(function(Descendant)
if Descendant:IsA("TextButton") or Descendant:IsA("ImageButton") then
--set up the connection
end
end)
The only problem with using an Added event is that if the button has already loaded in by the time the script is running, that button won’t be included.
Then that’s exactly why you’ll need to call Instance:WaitForChild() either in some sort of loop, to ensure all instances you’ll index will exist when you do, using DescendedAdded the implementation won’t function perfectly for this purpose .
The below response is what I’m talking about, that way you can ensure all objects will have replicated to the client.
local buttonNames = {"button1", "button2", "button3"}
for _, buttonName in ipairs(buttonNames) do
local button = screenGui:WaitForChild(buttonName)
button.MouseButton1Down:Connect(...)
end
I just tested your method, and it works very well!
function buyButton()
print("Buy")
end
function sellButton()
print("Sell")
end
script.Parent.DescendantAdded:Connect(function(item)
if item:IsA("TextButton") or item:IsA("ImageButton") then
if string.match(string.lower(item.Text), "sell") then
item.MouseButton1Down:Connect(sellButton)
end
if string.match(string.lower(item.Text), "buy") then
item.MouseButton1Down:Connect(buyButton)
end
end
end)
This script perfectly does what I need it to do. As for the pre-existing buttons that I know will always exist, I can always connect functions to those very easily. Thanks for the help everyone!
I guess I kind of assumed he was just wanted to wait for all instances to load in on the client before running the code. I did read the entire post and that’s just how I interpreted it. Anyway doesn’t matter now, problem is solved.