I want the part to give only one win when a player touches a part, but it adds more than one win when the part is touched

Hello, I have a script that gives wins (from leaderstats) when you touch a part, but I want the player to receive only one win when they touch the part, but they get more than 10 wins when they touch the part.

Here is a video about it (sorry if the video is laggy):
robloxapp-20210628-2127380.wmv (716.4 KB)

As you can see, the wins (and the money) is going up fast when a player touches the part.

Here is the script:

local Players = game:GetService("Players")

local finishLine = script.Parent

local function onPartTouch(otherPart)
	local partParent = otherPart.Parent
	local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
	if humanoid then
		-- Update the player's leaderboard stat
		local player = Players:GetPlayerFromCharacter(partParent)
		local leaderstats = player.leaderstats
		local moneyStat = leaderstats and leaderstats:FindFirstChild("Money")
		local winsStats = leaderstats and leaderstats:FindFirstChild("Wins")
		if moneyStat then
			moneyStat.Value = moneyStat.Value + 500
		end
		
		if winsStats then
			winsStats.Value = winsStats.Value + 1
		end
	end
end
finishLine.Touched:Connect(onPartTouch)

Also, I think I got this script from Roblox’s Code Sample.

Is there any way to make the script allow players to only have 1 wins if they touch the part?
Thank you.

local Players = game:GetService("Players")

local finishLine = script.Parent
local debounce = false
local cooldown = 2

local function onPartTouch(otherPart)
    local partParent = otherPart.Parent
    local player = Players:GetPlayerFromCharacter(partParent)
    if player and debounce == false then
        debounce = true
        -- Update the player's leaderboard stat
	    local leaderstats = player.leaderstats
	    local moneyStat = leaderstats and leaderstats:FindFirstChild("Money")
	    local winsStats = leaderstats and leaderstats:FindFirstChild("Wins")
	    if moneyStat then
	        moneyStat.Value += 500
	    end
	    if winsStats then
	        winsStats.Value += 1
	    end
        wait(cooldown)
        debounce = false
    end
end

finishLine.Touched:Connect(onPartTouch)

just add a debounce, also you shouldn’t use wait(cooldown) and instead a different yielding method

2 Likes

add a table that makes it so they cant touch it again

local Players = game:GetService("Players")

local finishLine = script.Parent

local hastouched = {}

local function onPartTouch(otherPart)
	local partParent = otherPart.Parent
	local humanoid = partParent:FindFirstChildWhichIsA("Humanoid")
	if humanoid then
		-- Update the player's leaderboard stat
		local player = Players:GetPlayerFromCharacter(partParent)
		if not hastouched[player] then
			hastouched[player] = true
			local leaderstats = player.leaderstats
			local moneyStat = leaderstats and leaderstats:FindFirstChild("Money")
			local winsStats = leaderstats and leaderstats:FindFirstChild("Wins")
			if moneyStat then
				moneyStat.Value = moneyStat.Value + 500
			end
			
			if winsStats then
				winsStats.Value = winsStats.Value + 1
			end
		end
	end
end
finishLine.Touched:Connect(onPartTouch)
5 Likes

To help you understand more, the issue you’re running into is that the character is made of multiple parts. The .Touched event fires when it’s touched by ANY part. Because there’s multiple parts, it fires multiple times.

Adding a cooldown (as shown in the first reply) is an excellent way to stop them from just racking up too many points too quickly, but only if you want them to be able to touch it multiple times. Change the cooldown value to what you want the time between touches to be.

Adding a table (as shown in the second reply) is also a valid alternative! Use this one if you want them to be able to touch this point only once.

Hope this helps explain what’s going on more!

2 Likes