Trouble with stopping the money from spamming

Hello, I am making a simulator, and part of it has you touch a part and you get a certain amount of money. The problem I am having is sometimes when you touch it, it gives you more than it is supposed to before it disappears. Is there a way to stop this?

Here is the script:

function onTouched(hit)
 if hit.Parent.Humanoid~= nil then
 local cash = game.Players:findFirstChild(hit.Parent.Name).leaderstats.Robux
  
		cash.Value = cash.Value + 2
		
  
			wait(0.001)
			
		script.Parent:Destroy()
		end
	end
 
script.Parent.Touched:connect(onTouched)

Try this:

function onTouched(hit)
 if hit.Parent.Humanoid~= nil then
 local cash = game.Players:findFirstChild(hit.Parent.Name).leaderstats.Robux
  wait(1)
		cash.Value = cash.Value + 2
		
  
			wait(0.001)
			
		script.Parent:Destroy()
		end
	end
 
script.Parent.Touched:connect(onTouched)

It could be because of Debounce, as Instance.Touched can fire multiple times if multiple parts touch at the same time. An easy way to fix this would be to wait a small amount of time before giving the cash, and preventing any other onTouched requests during that timeframe.

I just tried it and it didn’t really work, it gave me way more than it should’ve.

The issue is that there’s no conditional check when checking if a player will first hit the part, then keep hitting it over & over again

A debounce in simple terms is basically a firerate with an automatic gun; it prevents it from repeatedly firing over & over again but rather through a balanced way

If we only check the debounce once, then change it; it’ll only fire once for that specific player

local Activated = false

local function onTouched(hit)
    if hit.Parent:FindFirstChild("Humanoid") and Activated = false then
        Activated = true
        local player = game.Players:GetPlayerFromCharacter(hit.Parent)
        local cash = player:WaitForChild("leaderstats").Robux
        
        cash.Value += 2
        wait() --Apparently to prevent a random error
        script.Parent:Destroy()
    end
end

script.Parent.Touched:Connect(onTouched)
1 Like

Thank you, this seems to work great!

I guess I’m being really nitpicky and kind of off-topic, but wait() shouldn’t be used to prevent random Roblox errors. In fact, I think wait() should never be used at all, outside of benchmarking or very basic tutorials.
(I’m not talking about wait([number]), but something like wait(0.0001) will run into the same issues)

There’s a great topic by Kampfkarren that explains exactly why you shouldn’t use wait(), but here’s a short extract for this circumstance.

I’ve tested them myself, and yes, RunService.Heartbeat:Wait() and RunService.Stepped:Wait() are both almost exactly twice as fast as wait().

Fair enough; I was just wanting to appeal to the OP’s issue for the time being but if you do worry about using wait() then just do this I suppose

local RunService = game:GetService("RunService")
local Activated = false

local function onTouched(hit)
    if hit.Parent:FindFirstChild("Humanoid") and Activated = false then
        Activated = true
        local player = game.Players:GetPlayerFromCharacter(hit.Parent)
        local cash = player:WaitForChild("leaderstats").Robux
        
        cash.Value += 2
        RunService.Heartbeat:Wait()
        script.Parent:Destroy()
    end
end

script.Parent.Touched:Connect(onTouched)
1 Like