Touched fires the function many times in a row

Hello, I need help with a function sent by Touched in a Server Script in ServerScriptServer, the code consists of searching through a loop for all the coins in a folder (this to avoid placing the script directly inside each coin) and that when touching that coin and the Instance that touched that coin is a Humanoid so 1 point will be awarded to the player and the coin will be temporarily disabled

The problem is that touching the Part (coin) activates it several times at the same time, even though CanTouch practically deactivates at the beginning to prevent that, how can I prevent that from happening?

----I tried to use Debounce and Table.Find but it keeps repeating


The Script in ServerScriptService

for _,coin in pairs(coins) do
	if coin:IsA("BasePart") then
		if debounce == true then
			coin.Touched:Connect(function(hit)
				local player = Players:GetPlayerFromCharacter(hit.Parent)
				debounce = false
				if not hit.Parent:FindFirstChild("Humanoid") then return end
				coin.CanTouch = false
				coin.Transparency = 1

				debounce = true

				local GenerateSound = SoundService.SoundLibrary.Sounds.CoinPickup1:Clone()
				GenerateSound.Parent = coin
				GenerateSound:Play()

				player.leaderstats.Coins.Value += 1
				task.wait(5)

				coin.CanTouch = true
				coin.Transparency = 0
			end)
		end
	end
end

you have your if debounce == true then bit in the wrong spot. It should be contained within the .Touched event.

Also, your debounce should have a more significant delay before letting the player touch it again.

1 Like

You’ll need a separate debounce for each coin, plus I also noticed you’re creating a new Sound Instance using :Clone() and never seem to destroy them afterwards so I fixed that problem as well since otherwise your game will fill up with unwanted objects:

local Debris = game:GetService("Debris")

for _, coin in coins do
	if coin:IsA("BasePart") then
		local debounce

		coin.Touched:Connect(function(hit)
			if debounce then return end

			local player = Players:GetPlayerFromCharacter(hit.Parent)

			if player then
				debounce = true

				coin.Transparency = 1
				coin.CanCollide = false

				task.spawn(function()
					local GenerateSound = SoundService.SoundLibrary.Sounds.CoinPickup1:Clone()
					GenerateSound.Parent = coin
					GenerateSound:Play()
					GenerateSound.Ended:Wait()
					Debris:AddItem(GenerateSound, 0) -- I added this because I noticed that sounds were created repeatedly and never destroyed
				end)

				player.leaderstats.Coins.Value += 1
				task.wait(5)
				coin.Transparency = 0
				coin.CanCollide = true

				debounce = nil
			end
		end)
	end
end

Edit: An alternative way of achieving the same result is by doing this:

for _, coin in coins do
	if coin:IsA("BasePart") then
		local GenerateSound = SoundService.SoundLibrary.Sounds.CoinPickup1:Clone()
		GenerateSound.Parent = coin

		local debounce

		coin.Touched:Connect(function(hit)
			if debounce then return end

			local player = Players:GetPlayerFromCharacter(hit.Parent)

			if player then
				debounce = true

				coin.Transparency = 1
				coin.CanCollide = false

				GenerateSound:Play()

				player.leaderstats.Coins.Value += 1
				task.wait(5)
				coin.Transparency = 0
				coin.CanCollide = true

				debounce = nil
			end
		end)
	end
end

Each coin will have 1 sound object created only once

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.