How do I prevent wait(1)?

I’m currently creating a coin collecting system, but I am not sure how to do the debounce correctly. I’ve tried a couple of solutions, but still ended with the player getting more money than they should & etc.

Problem:

  • I’m trying to make it so when a player touches a coin or more coins quickly they get rewarded, but the debounce makes it so the player has to “wait” one second before picking up another coin.

  • I need help to figure out how to make it so there’s no recognizable debounce after a coin has been collected. That means that when a coin gets collected, the player is still able to collect other coins without having to wait a second (while still receiving the correct amount of money, once).

Collected = {}

PlayerService.PlayerAdded:Connect(function(Player)
	table.insert(Collected,Player.Name)
end)

Earth.ChildAdded:Connect(function()
	for _,Loot in ipairs(Earth:GetChildren()) do
		Loot.Main.Touched:Connect(function(hit)
			local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
			if not Collected[Player.Name] then
				local LootObject = Loot.Name
				local Amount = CollectValues.Earth[LootObject]
				LootService:Collect(Loot, Player, Amount)
				Collected[Player.Name] = true
				wait(1)
				Collected[Player.Name] = false
			end
		end)
	end
end)
--// The main module function that gives the money and does the effects, if needed.
function LootService:Collect(Object, Player, Amount)
	LootService:RewardMoney(Player, Amount)
	LootService:Sound(Object)
	LootService:Particles(Object)
	delay(1, function() --// This deletes the coin after it's been collected.
	if Object then
		Object:Destroy()
		end
	end)
end

Are we sure your debounce works, cus from this little bit of code it looks like it’s always false regardless

Instead of making the debounce on the player, why not make it on the object itself.

Loot.Main.Touched:Connect(function(hit)
	local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if not Collected[Loot] then
		local LootObject = Loot.Name
		local Amount = CollectValues.Earth[LootObject]
		LootService:Collect(Loot, Player, Amount)
		Collected[Loot] = true
		delay(1, function()
			Collected[Loot] = false
		end)
	end
end)
1 Like

I’m sorry, forgot that it was set to false after hit. I’ll try your solution now.

I’d also recommend adding more conditions to it, such that the delay should be the respawn time of the coin. However if the coin is removed after the player collects it there is even better ways to do something of this nature.

1 Like

In case the coin is removed upon collection or something of that nature, this would probably be better.

local Connections = {}

Earth.ChildAdded:Connect(function()
	for _,Loot in ipairs(Earth:GetChildren()) do
		if not Connections[Loot] then
			Connections[Loot] = Loot.Main.Touched:Connect(function(hit)
				local Player = game.Players:GetPlayerFromCharacter(hit.Parent)
				if Player then 
					local LootObject = Loot.Name
					local Amount = CollectValues.Earth[LootObject]
					LootService:Collect(Loot, Player, Amount)
					Connections[Loot]:Disconnect()
				end
			end)
		end
	end
end)

The way you have it now it looks like some objects are getting hit with more than one .Touched event, say you have a loot object and one spawns, then that one gets hit again. Either way, I hope any of this helps.

1 Like

Your first solution actually worked perfectly and there is not issues with the .Touched event from the first solution.

I’ll mark it as the solution if you agree that it’s fine to go that way.

I see, I just didn’t want the chance of overlapping them on each instance, because that can lead to some bad connection management. If you’re satisfied with the first option then by all means.

1 Like

I’ll use you second solution, since it is important that connection managment is good. Thanks for helping me though! I appriciate it a lot.

No problem, good luck with your ventures. Happy to help.

1 Like