Do not place scripts on each coin. You should perform the task with a Module. Each coin on touch/grab/ect, should be connected to the Module, asking for only one function to give the currency to the player.
Like, you run one function of the Coins_Module. That module search for coins placement, clone a coin from ServerStorage, place that model in workspace, connect a touch event to that coin, that calls another function in Module “CoinTaken” that function will perform the money giving based on the type of coin.
One function will be used for all coins in workspace, and all coins were created by another one function
local coins = {}
local Tokens = workspace:FindFirstChild("Tokens")
local ServerStorage = game:GetService("ServerStorage")
local CoinFolder = ServerStorage:FindFirstChild("Coins")
function coins.New(position, Type)
local desiredCoin = CoinFolder:FindFirstChild(Type)
local NewCoin = desiredCoin:Clone()
NewCoin.Parent = Tokens
NewCoin.Position = position
end
return coins
im unsure on the coin taking and respawning, its what puzzled me.
Sure, that works. I suppose you will be calling that module to create the coins many times, sending positions for the coins and the types.
Just for testing, Im would be calling that module with this script to create one coin at position 0,5,0. And sending a type “Gold”
local coins = require(script.Parent:WaitForChild("coins"))
wait(5)
warn("do coin")
coins.New(Vector3.new(0,5,0), "Gold")
Then the module would create that coin and after that connect an event, for my testing I included a ClickDectector in the Gold coin model part
local coins = {}
local Tokens = workspace:FindFirstChild("Tokens")
local ServerStorage = game:GetService("ServerStorage")
local CoinFolder = ServerStorage:FindFirstChild("Coins")
-- When a coin is clicked do stuff
coins.CoinTaken = function(player, CoinType, TheCoin)
warn(player, CoinType)
local PreviousPos = TheCoin.Position
TheCoin:Destroy()
-- WAIT 5 seconds to spawn that coin again
task.delay(5, function()
coins.New(PreviousPos, CoinType)
end)
end
coins.New = function(position, Type)
local desiredCoin = CoinFolder:FindFirstChild(Type)
local NewCoin = desiredCoin:Clone()
NewCoin.Parent = Tokens
NewCoin.Position = position
NewCoin:WaitForChild("ClickDetector").MouseClick:Connect(function(player)
coins.CoinTaken(player, Type, NewCoin)
end)
end
return coins
It prints on a warn the player and the coin they collected and destroy it after the click
local coins = {}
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local Tokens = workspace:FindFirstChild("Tokens")
local CoinFolder = ServerStorage:FindFirstChild("Coins")
-- When a coin is clicked do stuff
coins.CoinTaken = function(player, CoinType, TheCoin, state)
if not state then
state = true
warn(player, CoinType)
local PlayerToFind = Players:GetPlayerFromCharacter(player.Parent)
local LS = PlayerToFind:FindFirstChild("leaderstats")
LS.Tokens.Value += 1
CoinType.Collect:Play()
CoinType:Destroy()
local PreviousPos = TheCoin.Position
TheCoin:Destroy()
-- WAIT 5 seconds to spawn that coin again
task.delay(5, function()
coins.New(PreviousPos, CoinType)
state = true
end)
end
end
coins.New = function(position, Type)
local desiredCoin = CoinFolder:FindFirstChild(Type)
local NewCoin = desiredCoin:Clone()
NewCoin.Parent = Tokens
NewCoin.Position = position
NewCoin.Touched:Connect(function(player)
coins.CoinTaken(player, Type, NewCoin, false)
end)
end
return coins
ReplicatedStorage.CoinHandler:20: attempt to index nil with 'Play' - Server - CoinHandler:20
EDIT: I GOT IT TO WORK! IM JUST UNSURE WHY THE SOUND DOESN’T PLAY!
The sound doesn’t play because sound effects are client-sided, not server-sided. You should either play the sound effect on the client with a LocalScript when the user clicks the coin, or send a remote event to the user that plays the sound effect when triggered.