FindFirstChild() not working

I am trying to script a remote event that will change a value stored in a player when a GUI button is clicked. Currently, I am able to click the button on the client, and get the remote event to fire. The code that fires the event looks like this:
remote:FireServer(player, metal, -amount)
and it starts this function:

changeValue.OnServerEvent:Connect(function(player, value, amount)
	
	local newPlayer = game.Players:FindFirstChild(player.Name)
	print(newPlayer)
	local newValue = newPlayer.playerValues:FindFirstChild(value)
	print(newValue)
	newValue.Value += amount
	
end)

In the local script, player is set to Players.LocalPlayer, metal is set to “Bronze”, and amount is set to a number. When any player joins, I clone a folder into the player that contains a bunch of values called playerValues. Inside playerValues there is a value called Bronze, but the code can’t seem to find it. The print function prints nil for (newValue). Does anyone have any idea what is wrong?

2 Likes

Try putting a print(value) before local newValue and see what value is

1 Like

My code gets an error that says that I tried to index nil with value

When you fire a remote event from the client, you don’t need to add a player argument. Server scripts that handle remote events will automatically have a player parameter for the player who fired the event, so use remote:FireServer(metal, amount).

4 Likes

That means when you did FireServer you didnt properly set what metal was
(metal must of been nil so OnServerEvent would of received nil)

Thanks, that worked. If I would have read the dev hub more carefully I would have seen that. But now I have the problem that the value is getting set to minus three times what I want to sell, almost like the event is firing three times.

1 Like

I am using GUIbutton.Activated for when the button is pushed, maybe that is the problem?

changeValue.OnServerEvent:Connect(function(player, value, amount)
	
	print(player.Name)
	local newValue = player.playerValues:FindFirstChild(value)
	print(player.Name)
	newValue.Value += amount
	
end)

First things first, the line here is unnecessary:

local newPlayer = game.Players:FindFirstChild(player.Name)

This is unnecessary because the “player” variable already gives you the player instance, making it unneeded. However, maybe you were using this to just debug :FindFirstChild()

Wait, I think I see your problem.
remote:FireServer() ALWAYS sends the player that called it as the first argument. Even if you made sure the arguments were empty (like remote:FireServer()), it will still send the player instance.

So what ends up happening here, since you are calling remote:FireServer(Players.LocalPlayer,"Bronze",[INSERT_NUMBER]), what ACTUALLY gets sent is this:

remote:FireServer([INSERT_PLAYER_INSTANCE],Players.LocalPlayer,"Bronze",[INSERT_NUMBER])

Note: Things in the [] are not literal.

And since your OnServerEvent function expects only 3 arguments,
“player” gets set to [INSERT_PLAYER_INSTANCE],
“value” gets set to Players.LocalPlayer
“amount” gets set to “Bronze”
And the number argument gets discarded.

To fix this, just do remote:FireServer(metal,amount) like @MooMooManager suggested

1 Like