I have a folder with a list of TextButtons all of which are displayed on the screen. I want to find out which TextButton has been clicked and the name of it, but the script that I have wrote doesn’t seem to work. Here is the script.
local Players = game:GetService("Players")
local ScrollingFrame = Players.LocalPlayer:WaitForChild("PlayerGui").Cashier.partyFrame.ScrollingFrame
local PlayerNames = ScrollingFrame.PlayerNames -- this accesses the folder
for i,v in ipairs(PlayerNames:GetChildren()) do
v.MouseButton1Click:Connect(function()
print(v.Name)
end)
end
send a picture of your directory please, even if no error is encountered we need to better see what your’re referencing, there might be a better method
Using a script wouldn’t changing anything, I want all of this to be done on the client. I have also edited the previous script relating to your first problem with something that I didn’t include. You also did say use a script, but edited it when I said this.
I suggested that you move your localscript to the same relative place in the hierarchy so that it is easier to get your frame. Player.PlayerGui is not an efficient way to do this.
Edit: Use script.Parent.partyFrame.ScrollingFrame for getting your scrollingframe instead of using player.PlayerGui…children…ScrollingFrame.
local PlayerNames = script.Parent.partyFrame.ScrollingFrame.PlayerNames
for i,v in ipairs(PlayerNames:GetChildren()) do
v.MouseButton1Click:Connect(function()
print(v.Name)
end)
end
Yes, game:GetService(“Players”) should be used over game.Players to make sure Players has instantiated at the time of referencing.
@RyanTheLion911 If you use a Local Script this will all run for the LocalPlayer individually as it will have replicated separately for every Client.
Make sure you use :
local Players = game:GetService("Players")
The error is probably because as it is evident from your screenshot, not all children are buttons thus not all of them have the .MouseButton1Click event.
You would have to add an additional line of code to verify that the instance iterated over was actually a button first.
Demonstration :
local Players = game:GetService("Players")
local ScrollingFrame = Players.LocalPlayer:WaitForChild("PlayerGui").Cashier.partyFrame.ScrollingFrame
local PlayerNames = ScrollingFrame.PlayerNames -- this accesses the folder
for _,button in ipairs(PlayerNames:GetChildren()) do
if button:IsA("TextButton") then
button.MouseButton1Click:Connect(function()
print(button.Name)
end)
end
end
I already was accessing the player service by using game:GetServce(“Players”), I just forgot to add that into my first script. I can’t access the players by simply doing Players…
I will include another screenshot onto this post showing that in the folder, all of which are TextButtons. Checking to see if they are TextButtons will frankly make no difference. The folder specifically contains player names with buttons. These text buttons are made during the game.(https://gyazo.com/76ffddc4da03d32f7c12f6de277ef0bf)
eh… Actually a difference will definitely be made, sanity checks are important in different scenarios, if you check for whether something is a button you’re checking for whether it actually has the .MouseButton1Click Event, why? because if it doesn’t and you continue with your operation, an error will be encountered as the event simply put, doesn’t even exist for an instance otherwise, kind of like indexing nil.
What I should have been added to my previous code was a return, so that it returns end if the instance is not a button.
This is to demonstrate :
local Players = game:GetService("Players")
local ScrollingFrame = Players.LocalPlayer:WaitForChild("PlayerGui").Cashier.partyFrame.ScrollingFrame
local PlayerNames = ScrollingFrame.PlayerNames -- this accesses the folder
for _,button in ipairs(PlayerNames:GetChildren()) do
if not button:IsA("TextButton") then
return
end
button.MouseButton1Click:Connect(function()
print(button.Name)
end)
end
I don’t understand why this would be the necessary, all of the children of ‘PlayerNames’ are GUARANTEED to be TextButtons, as that is the only thing that is being added to that specific folder. I will try the code that you have just said, but I can’t see it making any difference.
Oh, I have no idea why this code isn’t working then. I’ll try it in a different studio and see if that makes any difference.
EDIT1: I definitely ran it in game, else the buttons wouldn’t of been created. I think that is where the problems lie, as the buttons are created while player is in the game, I believe that it is just looping through an empty table, there is no event to find when the TextButtons have actually been added. This exact code worked on a game when the player spawns with the TextButtons enabled.
The error was that during the game the labels were added, but the for loop was simply going through the folder at the start of the game, which contained nothing. I have to have an event to technically ‘reset’ the for loop to loop through the new items within the folder that have been added.
To do this, I used the ‘ChildAdded’ event. This allowed me to detect when a new item was added into the folder, and was the time that I had to ‘reset’ the for loop. I also put the code in a function to make it a bit more simple.
Code:
-- // variables //
local Players = game:GetService("Players")
local ScrollingFrame = script.Parent.partyFrame.ScrollingFrame
local PlayerNames = ScrollingFrame.PlayerNames
-- // functions //
local function OnAdded()
for _, v in ipairs(PlayerNames:GetChildren()) do
v.MouseButton1Click:Connect(function()
print(v.Name)
end)
end
end
-- // events //
PlayerNames.ChildAdded:Connect(OnAdded)
Thanks to everyone who helped me with this problem, it was a great help.
Players won’t consistently be added, they will be added once so this change isn’t needed as it’s going to make it the tiny bit more efficient, which isn’t noticeable. Also, :WaitForChild isn’t an event, so it can’t be connected to the function.
I don’t remember saying “Connect WaitForChild to a function” , all I said was it’s still comparatively much more efficient than frequently running repetitious code each time a player joins, just to make sure something exists.
also
It’s not only an event that can be “connected” to a function, and it’s not what I implied either.
As you can see on the Developer Hub itself, :WaitForChild in some scenarios is really crucial , if you can’t take my word for it