Why doesn't this script detect when a player has clicked a button?

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
4 Likes

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

1 Like

It doesn’t come up with an error.

EDIT: This is done in a local script.

1 Like

Is this a script or local script?

Edit from previous post was made after this post was sent.

1 Like

Regardless of relevance, it will definitely change everything, if you’re using a server script instead, the LocalPlayer property would be nil.

Without more resource we can’t help you, I implore you to send an image showing your directory/hierarchy of items you’re referencing.

1 Like

True, but I’m not using a server script so that is irrelevant.

1 Like

First off, you can not just use ‘Players’.
Use game:GetService(“Players”).

Next, you should put this localscript in the UI with the ScrollingFrame so that you dont have to find the PlayerGui as this may cause errors.

1 Like

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.

Also, below I have showed the hierarchy of items I have. https://gyazo.com/23964a662b206dcc00c4599db99fcaaf

EDIT2: Changing the way that the ScrollingFrame was accessed also made no difference.

1 Like

I did not say use a script.

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
1 Like
  1. 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…

  2. 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.

1 Like

Yes, I was talking referring to your previous code, because in that one not all the children were TextButtons, not your latest code.

This is what I’m trying to show you :

image

Code :

  local frame = script.Parent.Frame
     for _, button in ipairs(frame:GetChildren()) do
     print(button.Name)
 end

Output :

image

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.

Wait no, are you sure you used the code and then actually went into Play mode and then looked at the output right?

Running it in the command bar directly won’t even make sense as at that moment PlayerGui doesn’t exist.

PROBLEM SOLVED

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.

That is what I’ve done, not sure if I explained it correctly. I’m keeping it the same now as it works.

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