So basically i made a Leaderboard server script in ServerScriptService, it gives an individual coin value to each player and it works completely fine. I also made a local script for the coin system, and it’s in StarterPlayerScripts.
The problem is, when Player1 collects one coin for example, it shows on his screen that he has 1 coin, and Player2 has 0 coins. However, on Player2’s screen, it shows that Player2 has 1 coin and Player1 has 0 coins.
You should update the coin value on the server. Because the updates are done locally in your current code, when one client changes the value, no other client sees the change.
The reason why every client changes their own value is that you don’t check which player’s character touched the coin so every client will give themselves a coin when only one of them actually touches the coin.
To fix the problem, remove CoinVal.Value = CoinVal.Value + 1 from the local script and use the code below in your server script.
local Players = game:GetService("Players")
local CoinsFolder = workspace.Coins
local CoinTable = CoinsFolder:GetChildren()
local function onPlayerAdded(Player)
local leaderStats = Instance.new("Folder")
local Coins = Instance.new("IntValue")
Coins.Name = Coins
Coins.Value = 0
Coins.Parent = LeaderStats
leaderStats.Parent = Player
end
for _, Coin in CoinTable do
Coin.touched:Connect(function(Hit)
local Player = Players:GetPlayerFromCharacter(Hit.Parent)
if Player == nil then
return
end
local CoinValueObject = player:WaitForChild("leaderstats"):WaitForChild("Coins")
CoinValueObject.Value += 1
task.wait(0.5)
Coin:Destroy()
end
end
Players.PlayerAdded:Connect(onPlayerAdded)
Other things:
I recommend writing a line with ``` and writing / copy pasting your code under that line in your post instead of giving your code as screenshots.
I’m pretty sure that the argument given by Touched is never nil.
For performance reasons, it is recommended to set the parent of an instance after setting its other properties.
For better performance, I’d also recommend using the Changed event of CoinVal instead of a while loop for updating CoinDisplay.Text
Thanks it works, but now the coin value is just updating by random amounts?
--//Variables//--
local Players = game:GetService("Players")
--------------------------------------------
local CoinsFolder = workspace.Coins
local CoinTable = CoinsFolder:GetChildren()
--//Function//--
local function onPlayerAdded(Player)
------------------------------------------
local LeaderStats = Instance.new("Folder")
LeaderStats.Name = "leaderstats"
--------------------------------------
local Coins = Instance.new("IntValue")
Coins.Name = "Coins"
Coins.Value = 0
Coins.Parent = LeaderStats
---------------------------
LeaderStats.Parent = Player
end
--------------------------------------------
for _, Coin in pairs(CoinTable) do
local function onCoinTouched(Hit)
---------------------------------------------------------
local Player = Players:GetPlayerFromCharacter(Hit.Parent)
---------------------------------------------------------
if Player == nil then
return
end
--------------------------------------------------------------------------------
local LeaderStats = Player:WaitForChild("leaderstats")
local CoinVal = LeaderStats:WaitForChild("Coins")
CoinVal.Value = CoinVal.Value + 1
task.wait(0.5)
Coin:Destroy()
end
Coin.Touched:Connect(onCoinTouched)
end
--------------------------------------------
Players.PlayerAdded:Connect(onPlayerAdded)
-----------------------------------------------------
I forgot that the touched event will fire multiple times before the coin is destroyed. Changing Coin.Touched:Connect(onCoinTouched) to Coin.Touched:Once(onCoinTouched) should fix the problem because the connected function will then only be called when the Touched event fires for the first time.