Touched event activating more than once

  1. What is the issue? Touched event is fired even when mouse is not clicked. (For both heavy AND light)

  2. What solutions have you tried so far? I’ve researched this topic for a day and a half and I’ve came across no results that even vaguely matched my scenario.


local tool = script.Parent -- Gets the tool
local player = game:GetService("Players").LocalPlayer --Gets the player that is holding the tool
 
--local character = game.Players.LocalPlayer.Character -- Gets the player's character model
local animation = script:WaitForChild("Idle") -- Checks for the animation

local animator = player.Character:WaitForChild("Humanoid"):WaitForChild("Animator") -- Gets the animator from the player

local animationTrack = animator:LoadAnimation(animation) -- Loads the animation for it to be ready to use!

	 
 
local db = false

local hitDb = false

 

 



--Equip
tool.Equipped:Connect(function()
	

	
	animationTrack:Play() -- Play animation when equipped. If you want the animation to be a loop, make sure to click the loop icon when creating the animation!
	
	
	
	
	local uis = game:GetService("UserInputService")
	uis.InputBegan:Connect(function(k,gpe)
		if not gpe then
			if k.UserInputType == Enum.UserInputType.MouseButton1 then
				lightAttack()
			elseif k.UserInputType == Enum.UserInputType.MouseButton2 then
				heavyAttack()
			end
		end
	end)
	
	
	
	
	
	
end)



--Unequip
tool.Unequipped:Connect(function()
	animationTrack:Stop() 
	
	for i,v in pairs(player.Character.Humanoid:GetPlayingAnimationTracks()) do v:Stop() end-- Stops the animation
end)

local anims = {
	script:WaitForChild("slash(1)"),
	script:WaitForChild("slash(2)"),
	script:WaitForChild("slash(3)"),

} 

local heavyAnims = {
	script:WaitForChild("heavyAttack(1)"),
	script:WaitForChild("heavyAttack(2)"),
	script:WaitForChild("heavyAttack(3)"),
	script:WaitForChild("heavyAttack(4)"),
 
} 





-- Loads the animation for it to be ready to use

function lightAttack()
	
	print("attackingLightly")
	
	local animationTrackSwing = animator:LoadAnimation(anims[math.random(1, 3)])

	if db == true then return end
	if player.currentPlayerStats.isAttacking.Value == true then return end
	if player.currentPlayerStats.Endurance.Value - (player.playerStats.Endurance.Value *0.1) <=0 then return end

	db = true
	player.currentPlayerStats.isAttacking.Value = true

	player.currentPlayerStats.Endurance.Value -= (player.playerStats.Endurance.Value *0.1)


	animationTrackSwing:Play() -- Make sure this isn't a looped animation!


	script.Parent.Handle.Touched:Connect(function(hit)


				if hitDb == true then return end
					hitDb = true				
		calcDamage(hit)
		script["Stab Sound Effect"]:Play()
				wait(1.5)
				hitDb = false




	end)

	animationTrackSwing.Stopped:Wait()
	task.wait(0.1)
	
	player.currentPlayerStats.isAttacking.Value = false
	db = false

	if script.Parent.Parent.ClassName == "Humanoid" then -- checking to make sure this item is still equipped

		animationTrack:Play()

	end


	
end

function heavyAttack()
	print("AttackignHeavily")
			local ran = math.random(1, 3)
	local ats =  animator:LoadAnimation(heavyAnims[ran])
	if player.currentPlayerStats.isAttacking.Value == true then return end
	if db == true then return end
	if player.currentPlayerStats.Endurance.Value - (player.playerStats.Endurance.Value *0.2) <=0 then return end

	db = true
	player.currentPlayerStats.isAttacking.Value = true

	player.currentPlayerStats.Endurance.Value -= (player.playerStats.Endurance.Value *0.2)



	if ran ~= 3  then 
		
		ats:Play(0.1,1,0.9)
	else
		ats:Play(0.1,1,0.3)
	end
	 -- Make sure this isn't a looped animation!
	--make this animation slower so it can feel like a heavy attack
	
	
	script.Parent.Handle.Touched:Connect(function(hit)
		
	
		if hitDb == true then return end
		hitDb = true				
		calcHeavyDamage(hit)
		script["Stab sound effect"]:Play()
		wait(1.4)
		hitDb = false
		
		
		
		
		
	end)
	
	
	
   

ats.Stopped:Wait()
	task.wait(0.1)

	player.currentPlayerStats.isAttacking.Value = false
	db = false

	if script.Parent.Parent.ClassName == "Humanoid" then -- checking to make sure this item is still equipped

			
		animationTrack:Play()

	end
	
end

function calcDamage(victim)

	local Character = victim.Parent

	--damage formula

	local finalDamage = 1

	local strength = player.currentPlayerStats.Strength.Value

	local dexterity = player.currentPlayerStats.Dexterity.Value

	local wrath = player.currentPlayerStats.Wrath.Value

	local agility = player.currentPlayerStats.Agility.Value

	local critChance =4

	local critBoost = 2

	critBoost += (wrath * .25)

	critChance += dexterity *2

	local critical = false

	local currentCrit = math.random(critChance,100)

	if currentCrit == critChance then 

		critical = true

	end

	finalDamage = tool:GetAttribute("Damage")

	finalDamage *= (strength * .4)




	if critical == true then finalDamage *=critBoost end






	local enemyAgility = Character.Stats.Agility.Value

	local enemyDodgeChance = math.floor( enemyAgility / agility ) 

	if (enemyDodgeChance > 1) then

		if enemyDodgeChance >=100 then

			finalDamage = 0
		else

			local chance = math.random(enemyDodgeChance,100)

			if (chance == enemyDodgeChance) then

				finalDamage = 0
			end

		end

	end 

	Character.Humanoid.Health -= finalDamage
	
	local updNpcHealth = game.ReplicatedStorage.updNpcHealth
	updNpcHealth:FireServer(Character.Humanoid.Health,Character)
 
	
	
	
	print("Light Damage: ",finalDamage)
end

function calcHeavyDamage(victim)
	
	
	local Character = victim.Parent

	--damage formula

	local finalDamage = 1

	local strength = player.currentPlayerStats.Strength.Value

	local dexterity = player.currentPlayerStats.Dexterity.Value

	local wrath = player.currentPlayerStats.Wrath.Value

	local agility = player.currentPlayerStats.Agility.Value

	local critChance =4

	local critBoost = 2

	local heavyAttackBoost = 1.45

	heavyAttackBoost += (dexterity*.05)

	critBoost += (wrath * .25)

	critChance += dexterity *2

	local critical = false

	local currentCrit = math.random(critChance,100)

	if currentCrit == critChance then 

		critical = true

	end

	finalDamage = tool:GetAttribute("Damage")

	finalDamage *= (strength * .4)


	finalDamage *= heavyAttackBoost

	if critical == true then finalDamage *=critBoost end






	local enemyAgility = Character.Stats.Agility.Value

	local enemyDodgeChance = math.floor( enemyAgility / agility ) 

	if (enemyDodgeChance > 1) then

		if enemyDodgeChance >=100 then

			finalDamage = 0
		else

			local chance = math.random(enemyDodgeChance,100)

			if (chance == enemyDodgeChance) then

				finalDamage = 0
			end

		end

	end 

	Character.Humanoid.Health -= finalDamage
	
	local updNpcHealth = game.ReplicatedStorage.updNpcHealth
	updNpcHealth:FireServer(Character.Humanoid.Health,Character)

	
	print("Heavy Damage: ",finalDamage)
	
end

You are going to have to track the players swinging state and only connect the touch event if the play IS swinging.
Additionally, you should also set a connection variable to be equal to the touched event, and then at the end of the attack function, or after the animation is finished or whatever, disconnect that touched event to stop listening for touches.

For example:

function lightAttack()
-- Before the touch event --
local connection
connection = script.Parent.Handle.Touched:Connect(function(hit)

end)

animationTrackSwing.Stopped:Wait()
-- Disconnect the touch event to STOP listening for hits
connection:Disconnect()
task.wait(0.1)
player.currentPlayerStats.isAttacking.Value = false
db = false
if script.Parent.Parent.ClassName == "Humanoid" then
	animationTrack:Play()
end

Try this, and what I said above. I can’t really test it, but tracking the player’s swinging should work.

thanks. Fixed the connection issue, but i can’t use it inside of the function itself. I want to make it disconnect soon as the first hit is registered

it says unknown global connection, while im inside the connect variabel