Can someone please help me with this system?

Hello! So I have a system where every time the player touches a checkpoint, they get 10 coins. The problem is, the debounce doesn’t work and you should only be able to touch it once per join. (I don’t know how to script that last part.) Could someone please help me debounce this and implement the latter?

local Stages = script.Parent
local Sound = Stages:WaitForChild("Sound")

local debounce = true

game.Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Player:WaitForChild("leaderstats")
	local Coins = leaderstats:WaitForChild("Coins")
	
	for _, part in pairs(Stages:GetChildren()) do
		if part:IsA("SpawnLocation") then
			part.Touched:Connect(function(hit)
				if debounce then 
					debounce = false
					if hit.Parent:FindFirstChild("Humanoid") then
						Coins.Value += 10
						Sound:Play()
						debounce = true
					end
				end
			end)
		end
	end
end)

Thank you for your help and feedback! Have a wonderful day! :slight_smile:

5 Likes

Make a table of players that have touched the part, and remove players from the table when they leave the game

What would that look like? Could you show me please? I’m not the best scripter lol.

1 Like
local cooldown = {}

script.Parent.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)

	if player and not table.find(cooldown,player) then
		-- Give coins
		table.insert(cooldown, player)
	end
end)

game.Players.PlayerRemoving:Connect(function(player)
	if table.find(cooldown, player) then
		table.remove(cooldown, table.find(cooldown,player))
	end
end)

It worked for the most part, except only the first stage gives me coins and none of the others.
Full script:

local Stages = script.Parent
local Sound = Stages:WaitForChild("Sound")

local debounce = true

local Cooldown = {}

game.Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Player:WaitForChild("leaderstats")
	local Coins = leaderstats:WaitForChild("Coins")
	
	for _, part in pairs(Stages:GetChildren()) do
		if part:IsA("SpawnLocation") then
			part.Touched:Connect(function(hit)
				if Player and not table.find(Cooldown, Player) then
					if debounce then 
					debounce = false
					if hit.Parent:FindFirstChild("Humanoid") then
							Coins.Value += 10
							Sound:Play()
							debounce = true
							table.insert(Cooldown, Player)
						end
					end
				end
			end)
			
			if part.Name == "Stage 20" then
				Coins.Value += 100
			end
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	if table.find(Cooldown, Player) then
		table.remove(Cooldown, table.find(Cooldown, Player))
	end
end)

Is the script in a folder with the stages?

I wanna just make a comment but that loop runs everytime a player joins and wastes memory for bo reason

Yes the script is a folder with 20 stages inside.

The only reason I put the loop inside the PlayerAdded function was to get the player. This script is running server-sided, and not locally, so I’m not really sure how to the player in this case.

Just a test, try placing the debounce variable before the if statement like:

local debounce = true
if debounce then 
	debounce = false
	-- your code stuff
	debounce = true
end

Im talking about the spwan points loop… You should put it on the outside

Like this?

part.Touched:Connect(function(hit)
			if debounce then
				debounce = false
				if Player and not table.find(Cooldown, Player) then
					if hit.Parent:FindFirstChild("Humanoid") then
						Coins.Value += 10
						Sound:Play()

I also noticed that the value no longer goes up when any stage is touched. This script could play a part in it.

local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local CoinStore = DataStoreService:GetDataStore("CoinStorePractice3")

Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = Player
	
	local Coins = Instance.new("NumberValue")
	Coins.Value = 0
	Coins.Name = "Coins"
	Coins.Parent = leaderstats
	
	local data
	
	local success, errorMessage = pcall(function()
		data = CoinStore:GetAsync(Player.UserId.."_Coins")
	end)
	
	if data ~= nil then
		Coins.Value = data[1]
	end
end)

Players.PlayerRemoving:Connect(function(Player)
	local leaderstats = Player:WaitForChild("leaderstats")
	local Data = {}
	Data[1] = leaderstats.Coins.Value
	local success, errorMessage = pcall(function()
		CoinStore:SetAsync(Player.UserId.."_Coins", Data)
	end)
	if not success then warn(errorMessage) end
end)

My fault, I forgot to clarify. I meant it like this:

	for _, part in pairs(Stages:GetChildren()) do
		if part:IsA("SpawnLocation") then
			part.Touched:Connect(function(hit)
				if Player and not table.find(Cooldown, Player) then
					local debounce = true -- right here
					if debounce then 
					debounce = false
					if hit.Parent:FindFirstChild("Humanoid") then
							Coins.Value += 10
							Sound:Play()
							debounce = true
							table.insert(Cooldown, Player)
						end
					end
				end
			end)

Right where my comment is. Try it, and see if it has any effect or if it remains the same.

The problem is that you declared debounce outside of the function so it is global and a few other problems.
Here is a (hopefully) fixed version:

local Stages = script.Parent
local Sound = Stages:WaitForChild("Sound")

local Cooldown = {}

game.Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Player:WaitForChild("leaderstats")
	local Coins = leaderstats:WaitForChild("Coins")

	for _, part in pairs(Stages:GetChildren()) do
		if part:IsA("SpawnLocation") then
			local debounce = true
			
			part.Touched:Connect(function(hit)
				if Player and not table.find(Cooldown, Player) then
					if debounce then 
						
						if hit.Parent:FindFirstChild("Humanoid") then
							debounce = false
							
							if part.Name == "Stage 20" then
								Coins.Value += 100
							else
								Coins.Value += 10
							end
							
							Sound:Play()
							
							table.insert(Cooldown, Player)
							
							-- debounce = true   keep this line commented if you don't want the player to press the checkpoint multiple times.
							
						end
						
					end
				end
			end)

			
		end
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	if table.find(Cooldown, Player) then
		table.remove(Cooldown, table.find(Cooldown, Player))
	end
end)

i also moved the part.name = stage 20 to when the part is touched so that not all players get 100 coins in the beginning, unless that is what you want.

Also, debounce has to be declared outside of the part.Touched, but inside of the

part:IsA(“SpawnLocation”)

this is because then the debounce won’t work. The debounce local variable is located inside of the part:IsA(“SpawnLocation”) and inside of the loop so that each spawn location has their own local debounce variable.
Hope this helps!

1 Like

The Coins value doesn’t update when the player touches any stage beside Stage 1. Stage 20 doesn’t work, either.

I found the fix:

local Stages = script.Parent
local Sound = Stages:WaitForChild("Sound")

--local Cooldown = {}

game.Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Player:WaitForChild("leaderstats")
	local Coins = leaderstats:WaitForChild("Coins")

	for _, part in pairs(Stages:GetChildren()) do
		if part:IsA("SpawnLocation") then
			local debounce = true

			part.Touched:Connect(function(hit)
				if Player then --and not table.find(Cooldown, Player)
					if debounce then 

						if hit.Parent:FindFirstChild("Humanoid") then
							debounce = false

							if part.Name == "Stage 20" then
								Coins.Value += 100
							else
								Coins.Value += 10
							end

							Sound:Play()

							--table.insert(Cooldown, Player)

							-- debounce = true   keep this line commented if you don't want the player to press the checkpoint multiple times.

						end

					end
				end
			end)


		end
	end
end)

game.Players.PlayerRemoving:Connect(function(Player)
	--[[if table.find(Cooldown, Player) then
		table.remove(Cooldown, table.find(Cooldown, Player))
	end]]
end)

I removed the cooldown table, and this should work perfectly. The cooldown table seems to be pointless because there is already a debounce that shouldn’t allow the player to collect the checkpoint again, and the table was adding a cooldown at the first checkpoint. This stops the player from being able to collect the other checkpoints.
Hope this helps!

3 Likes

It worked! Thank you so much! Have a great rest of your day!

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