Hello Everyone! I’ve made coin collecting, but it’s working not properly. Let me explain, I have coin and I can take it. And I wrote script that when I’m touching it it gives me 1 coin. But it’s gives me not one, but more. And I don’t know why but my DataStore for coins not working properly.
Coin Collecting Script:
local players = game:GetService("Players")
local player = players.LocalPlayer
local char = script.Parent
local humanoid = char:FindFirstChild("Humanoid")
local soundService = game:GetService("SoundService")
local coinSound = soundService.SFX.Coin
humanoid.Touched:Connect(function(part)
if part.Name == "Coin" then
player.leaderstats.Coins.Value += 1
coinSound:Play(); part:Destroy()
task.wait(5)
local clone = part:Clone()
part.Parent = workspace.Coins
part.CFrame = part.CFrame
end
end)
DataStore Script:
local players = game:GetService("Players")
local ds = game:GetService("DataStoreService")
local statsDS = ds:GetDataStore("StatsDataStore")
players.PlayerAdded:Connect(function(player)
wait(1)
local userId = player.UserId
local stat = player.leaderstats.Coins
local getSaved = statsDS:GetAsync(userId)
if getSaved then
print(getSaved)
stat.Value = getSaved[1]
end
end)
players.PlayerRemoving:Connect(function(player)
local userId = player.UserId
local data = {player.leaderstats.Coins.Value};
local success, result = pcall(function()
statsDS:SetAsync(userId, data)
end)
if success then print("Stats successfuly saved!")
else warn(result) end
end)
If someone help, it would be really appreciated! Thanks.
You’re not supposed to change the stats of a player locally if you intend on saving it in a Datastore
The coin collecting script should be a server-side script and I would recommend using debounces for hit detection to avoid collecting more than 1 coin from the same coin.
Also if you want to get the player from a character for your hit detection (Which should not be a local script), I strongly recommend learning about :GetPlayerFromCharacter()
First of all, both scripts must be server scripts. Secondly, you need to add a debounce so that the player only gets 1 coin.
Also, a humanoid cannot touch anything since it’s not a basepart.
How I would do it:
Create a script inside the coin itself (I recommend collection service or any other way instead of making a script inside every coin)
Then, try something like this:
local Coin = script.Parent -- This should be the coin
local Debounce = false
Coin.Touched:Connect(function(hit)
local Character = hit.Parent
if game.Players:GetPlayerFromCharacter(Character) and Debounce == false then
local Player = game.Players:GetPlayerFromCharacter(Character)
Player.leaderstats.Coins.Value += 1
Debounce = true
Coin.Parent = game.ServerStorage -- take the coin inside server storage (maybe inside a folder)
task.wait(5) -- The cooldown between the coin respawn
Debounce = false
Coin.Parent = game.Workspace
end
end)
This script might not work, however it should give you a good idea on how it should be.
Is the coin a part or a model? It should be a part for this to work correctly.
Also, try this for debugging:
local Coin = script.Parent -- This should be the coin
local Debounce = false
Coin.Touched:Connect(function(hit)
print(hit.Name)
local Character = hit.Parent
if game.Players:GetPlayerFromCharacter(Character) and Debounce == false then
local Player = game.Players:GetPlayerFromCharacter(Character)
Player.leaderstats.Coins.Value += 1
Debounce = true
Coin.Parent = game.ServerStorage -- take the coin inside server storage (maybe inside a folder)
task.wait(5) -- The cooldown between the coin respawn
Debounce = false
Coin.Parent = game.Workspace
else
print("Player not found.")
end
end)
It should work with a union too. By any chance, did you group the union?
Also, does it have CanTouch on in properties?
For the last time, try this script for debugging:
local Coin = script.Parent -- This should be the coin
local Debounce = false
print("Script is running")
Coin.Touched:Connect(function(hit)
print(hit.Name)
local Character = hit.Parent
if game.Players:GetPlayerFromCharacter(Character) and Debounce == false then
local Player = game.Players:GetPlayerFromCharacter(Character)
Player.leaderstats.Coins.Value += 1
Debounce = true
Coin.Parent = game.ServerStorage -- take the coin inside server storage (maybe inside a folder)
task.wait(5) -- The cooldown between the coin respawn
Debounce = false
Coin.Parent = game.Workspace
else
print("Player not found.")
end
end)
If it still has no output, can you show me a screenshot of the union in the explorer?
Glad it helped. You will probably need to find a way to optimize this script, since having 100 coins with a script each can lag the game. A good idea can be putting all coins in a folder, having 1 script that does a for loop inside the folder, then doing the script.
Example:
local Folder = script.Parent
for i,v in pairs(Folder:GetChildren()) do -- (v is the child, probably the coin)
if v.Name == "Coin" then -- this is to check if its actually a coin or the script itself
-- run script here (but replace Coin with v)
end
end
This might not work, but it should give you a good idea on how to make your script more optimized. Good luck on your game.