I want to make a coin system where when you collect a coin it plays the sound locally. I used a RemoteEvent to do this with a single coin, this is the code I used.
Code
Local Script:
local coin = game.Workspace.Coin
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local coinCollection = ReplicatedStorage:WaitForChild("coinCollection")
local SoundService = game:GetService("SoundService")
local coinSound = Instance.new("Sound")
coinSound.Name = "CoinSound"
coinSound.SoundId = "rbxassetid://"..3302699870
coinSound.Parent = game.Workspace
local debounce = true
coin.Touched:Connect(function(player)
if debounce == true then
if player.Parent:FindFirstChild("Humanoid") ~= nil and player.Parent.Name == game.Players.LocalPlayer.Name then
wait()
debounce = false
coinCollection:FireServer()
coinSound:Play()
wait(10)
debounce = true
end
end
end)
Server Script:
local Players = game:GetService("Players")
local coin = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local coinCollection = ReplicatedStorage:WaitForChild("coinCollection")
function debounce(func)
local isRunning = false
return function(player)
if not isRunning then
isRunning = true
func(player)
isRunning = false
end
end
end
coinCollection.OnServerEvent:Connect(debounce(function(player)
coin.Transparency = 1
local player = player
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 1
wait(10)
coin.Transparency = 0
end))
Although this works fine with just 1 coin, I am puzzled on how I could get this to work with multiple coins.
First, you should put the script on the server. The .Touched connection is enough to handle it, and there is no need for a remote event.
Then you can clone the coin with a while loop and add a .Touched connection each time.
Edit: If you want a .Touched on the client for the sound to play locally, then have a .ChildAdded connection on the local script that makes a .Touched connection if the added child is a coin.
Ok thanks for that suggestion!
I have never used CollectionService before so I am having some issues. I have this code so far:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local coinCollection = ReplicatedStorage:WaitForChild("coinCollection")
local SoundService = game:GetService("SoundService")
local coinSound = Instance.new("Sound")
coinSound.Name = "CoinSound"
coinSound.SoundId = "rbxassetid://"..3302699870
coinSound.Parent = game.Workspace
local CollectionService = game:GetService("CollectionService")
local taggedCoins = CollectionService:GetTagged("Coin")
local debounce = true
for _, taggedCoins in pairs(taggedCoins) do
taggedCoins.Touched:Connect(function(hit)
if debounce == true then
if hit.Parent:FindFirstChild("Humanoid") ~= nil and hit.Parent.Name == game.Players.LocalPlayer.Name then
wait()
debounce = false
coinSound:Play()
coinCollection:FireServer()
wait(10)
debounce = true
end
end
end)
end
But whenever I run over 1 coin, the rest also collect. I’m fairly certain this issue is coming from the FireServer line but I’m not 100% sure if it is and how I would fix it.
Did you add the tag to collect the coin? Also, you don’t really need fireserver() for this particular thing. You could simply put this in one function and inside that function you add the add for the coin.
function giveCoin(coin)
-- code for giving the player the coin every time they touch it
CollectionService:AddTag(coin, 'Coin')
end
I used the Tag Editor plugin to add the tag to the coins. I used a LocalScript for the code shown above, so would you recommend switching to a server script then fire the client where it will play a sound locally?
No you don’t need to use this on the server. Since all you want to do is play the sound locally, this can be in a local script or module script in replicatedstorage or wherever the client the access it.
All you’d do is add the tag and every time the player touches it, it plays the sound.
function coinSound(coin)
-- touched function
CollectionService:AddTag(coin, 'Coin')
end
CollectionService:GetInstanceAddedSignal('Coin'):Connect(coinSound)
CollectionService:GetInstanceRemovedSignal('Coin'):Connect(coinSound)
for _, inst in pairs(CollectionService:GetTagged('Coin')) do
coinSound(inst)
end
Edit: Going to assume you are handling the coin spawning and despawning, if not let me know.
I was handling the coin spawning and respawning on the server script which would have been fired before, that is also where I would change the players leaderstats.
Oh so let me clarify, all you want to do is just play a sound and that’s it? Or play a sound and change leaderstats? If you’re going to try and change leaderstats then obviously do this on the server. But since you said you just wanted to play a sound I assumed you just wanted this local
Basically what I want to do is a sound played locally, leaderstats changed and also the changes to the coin’s transparency. Im fairly certain you cant play a sound locally from a server script so would a fireclient have to be used when the coin is collected to then play a sound from a local script?