Help with touch event

It’s hitting the logs twice really fast when I only need it to touch it once. Causing me to get double the amount of Chops in the leaderboard.

Here’s the local script:

local Hitbox = script.Parent
local IsSwinging = script.Parent.Parent:WaitForChild("IsSwinging")
local LogsChoppedRemote = game.ReplicatedStorage:WaitForChild("LogsChoppedRemote")
local ChopMultiplierValue = script.Parent.Parent:WaitForChild("ChopMultiplier").Value
local Hitsound = script.Parent.Parent.Handle:WaitForChild("HitSound")
local player = game:GetService("Players").LocalPlayer

-- Table to keep track of hit logs
local hitLogs = {}

Hitbox.Touched:Connect(function(hit)
	if IsSwinging.Value == true then
		if hit:IsA("BasePart") and not hitLogs[hit] then
			hitLogs[hit] = true

			local GiveChop
			if hit.Name == "Log" then
				GiveChop = 1
			elseif hit.Name == "ShinyLog" then
				GiveChop = 2
			elseif hit.Name == "GalaxyLog" then
				GiveChop = 4
			elseif hit.Name == "CartoonLog" then
				GiveChop = 10
			else
				GiveChop = 0
			end

			if GiveChop > 0 then
				LogsChoppedRemote:FireServer(GiveChop, ChopMultiplierValue, hit, Hitsound)
				print(player.Name .. " chopped a " .. hit.Name:lower() .. ".")
			end
		end
	end
end)

Here’s my server Script:

local LogsChoppedRemote = game.ReplicatedStorage:WaitForChild("LogsChoppedRemote")

-- Table to keep track of processed logs
local processedLogs = {}

-- Define the maximum level
local MAX_LEVEL = 9999999

-- Function to update player level based on their current chops
local function updateLevel(plr)
	local leaderstats = plr:FindFirstChild("leaderstats")
	if leaderstats then
		local Chops = leaderstats:FindFirstChild("Chops")
		local Level = leaderstats:FindFirstChild("Level")
		if Chops and Level then
			-- Calculate the level based on chops
			local newLevel = math.floor(Chops.Value / 100)
			-- Ensure level does not exceed the maximum level
			if newLevel > MAX_LEVEL then
				newLevel = MAX_LEVEL
			end
			-- Set the player's level
			Level.Value = newLevel
		end
	end
end

-- Connect to player joining event to initialize their level
game.Players.PlayerAdded:Connect(function(plr)
	-- Initialize the player's level when they join the game
	updateLevel(plr)
end)

LogsChoppedRemote.OnServerEvent:Connect(function(plr, GiveChop, ChopMultiplierValue, hit, HitSound)
	if plr and hit:IsA("BasePart") then
		if not processedLogs[hit] then
			processedLogs[hit] = true

			local FinalAddon = GiveChop * ChopMultiplierValue
			local leaderstats = plr:FindFirstChild("leaderstats")
			if leaderstats then
				local Chops = leaderstats:FindFirstChild("Chops")
				local Level = leaderstats:FindFirstChild("Level")
				if Chops and Level then
					Chops.Value = Chops.Value + FinalAddon
					HitSound:Play()
					print(plr.Name .. " has received " .. GiveChop * ChopMultiplierValue .. "Chop(s).")

					-- Check for milestones and update level accordingly
					local milestoneReached = math.floor(Chops.Value / 100) * 100
					if milestoneReached >= 100 and milestoneReached <= 1000000 then
						-- Ensure the player doesn't level up multiple times for the same milestone
						if Chops.Value >= milestoneReached and Level.Value < milestoneReached / 100 then
							-- Ensure that level does not exceed the maximum level
							if Level.Value < MAX_LEVEL then
								Level.Value = Level.Value + 1
								print(plr.Name .. " has reached level " .. Level.Value)
							end
						end
					end

					-- Immediately destroy the hit object
					hit:Destroy()
				end
			end
		end
	end
end)

Help is appreciated, thanks!

You can try using the :Once() method, which disconnects the signal right after it’s been fired.

function onSwing(hit)
	if IsSwinging.Value == true then
		if hit:IsA("BasePart") and not hitLogs[hit] then
			hitLogs[hit] = true

			local GiveChop
			if hit.Name == "Log" then
				GiveChop = 1
			elseif hit.Name == "ShinyLog" then
				GiveChop = 2
			elseif hit.Name == "GalaxyLog" then
				GiveChop = 4
			elseif hit.Name == "CartoonLog" then
				GiveChop = 10
			else
				GiveChop = 0
			end

			if GiveChop > 0 then
				LogsChoppedRemote:FireServer(GiveChop, ChopMultiplierValue, hit, Hitsound)
				print(player.Name .. " chopped a " .. hit.Name:lower() .. ".")
			end
		end
	end
end

Hitbox.Touched:Once(onSwing) -- Will disconnect itself after someone touches it

did you try adding debounce?
if should look smt like this

local db = true
local part  = workspace.Baseplate

part.Touched:Connect(function()
	if db then
		db = false
		--ur code
		
		
		-- at the end of ur code
		task.wait(1) -- how mcuh to wait 
		db = true
	end
end)

and if u want the log to fire “ONLY” 1 time athen use :Once instead of :Connect | if u used :Once then the event will fire for only 1 time and then disconnect itself | it will stop working if anything touched it so if ur checking if a (player/specific thing) touched the log then use debounce instead

local part  = workspace.Baseplate

part.Touched:Once(function()
	--ur code here
end)

Are you hitting multiple log hitParts at once? Maybe instead of the debounce being per part you could do per part’s parent so the model that part is in , or just a more general debounce for hitting any log would just allow a single log hit through per swing.