Need help with knife cooldown/hitbox

  1. What do you want to achieve? I want to make a knife that has a 2 second slashing cooldown and doesn’t have a glitchy hitbox.

  2. What is the issue? The slash and cooldown works fine when you don’t hit a player. However, the moment the blade touches a person, there is suddenly no more cooldown and you can spam them (not good). The hitbox is also weird. After the swing animation is done, the knife will still damage the player for around 1-2 seconds.

  3. What solutions have you tried so far? I have tried moving the debounce in the code and changing around the wait times, but honestly I’m clueless.

I’m pretty new to scripting so maybe I’m just stupid but I can’t figure it out for the life of me. Here is my knife code:

local knife = script.Parent
local handle = script.Parent.Handle

local holdChar = knife.Parent
local holdPlayer = game:GetService("Players"):GetPlayerFromCharacter(holdChar)

local backpackPlayer = knife.Parent.Parent
local backpackChar = backpackPlayer.Character

local slash = script:WaitForChild("Slash")
local debounce = false

local function knifeDamage()
	handle.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= knife.Parent then

			if debounce == true then

				hit.Parent.Humanoid.Health = hit.Parent.Humanoid.Health - 40
				debounce = false

				if hit.Parent.Humanoid.Health == 0 then
					if holdPlayer then
						holdPlayer.leaderstats.Coins.Value = holdPlayer.leaderstats.Coins.Value + 10
						holdPlayer.leaderstats.Kills.Value = holdPlayer.leaderstats.Kills.Value + 1
					elseif backpackPlayer then
						backpackPlayer.leaderstats.Coins.Value = backpackPlayer.leaderstats.Coins.Value + 10
						backpackPlayer.leaderstats.Kills.Value = backpackPlayer.leaderstats.Kills.Value + 1
					end
				end
			end
		end
	end)
end

knife.Activated:Connect(function()
	if debounce == false then
		debounce = true
		
		local humanoid = knife.Parent:WaitForChild("Humanoid")
		local animTrack = humanoid:LoadAnimation(slash)
		
		animTrack:Play()
		knifeDamage()
		task.wait(2)
		debounce = false
	end
end)

If anyone could help, that would be greatly appreciated!

The animation and damage aren’t working with that.
Could it be that I’m setting the debounce back to false right after I damage the player, resetting the cooldown? I’m not sure how to set a cooldown for the activated event.

try again, i updated the code.

I can spam the animation and damage still doesn’t work. Should I have the debounce strictly in the Activated event? Therefore it only sets the debounce back after the animation plays? But I’m still not sure about the cooldown, I’ve tried multiple places for the debounce and wait, but it never seems to work.

just remove the debounce inside the function

local knife = script.Parent
local handle = script.Parent.Handle

local holdChar = knife.Parent
local holdPlayer = game:GetService("Players"):GetPlayerFromCharacter(holdChar)

local backpackPlayer = knife.Parent.Parent
local backpackChar = backpackPlayer.Character

local slash = script:WaitForChild("Slash")
local debounce = false

local function knifeDamage()
	handle.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= knife.Parent then


				hit.Parent.Humanoid.Health = hit.Parent.Humanoid.Health - 40

				if hit.Parent.Humanoid.Health == 0 then
					if holdPlayer then
						holdPlayer.leaderstats.Coins.Value = holdPlayer.leaderstats.Coins.Value + 10
						holdPlayer.leaderstats.Kills.Value = holdPlayer.leaderstats.Kills.Value + 1
					elseif backpackPlayer then
						backpackPlayer.leaderstats.Coins.Value = backpackPlayer.leaderstats.Coins.Value + 10
						backpackPlayer.leaderstats.Kills.Value = backpackPlayer.leaderstats.Kills.Value + 1
					end
				end
		end
	end)
end

knife.Activated:Connect(function()
	if debounce == false then
		debounce = true
		
		local humanoid = knife.Parent:WaitForChild("Humanoid")
		local animTrack = humanoid:LoadAnimation(slash)
		
		animTrack:Play()
		knifeDamage()
		task.wait(2)
		debounce = false
	end
end)

Ok so this is going to be a long one.
So the best way to detect if a Player is in an area is by using workspace:GetPartsBoundInBox() and also you are loading the animation every time you activate the knife, causing the Animation to break after activating enough times.
Here is my version with the suggested changes.
Local script (in tool)

local knife = script.Parent
local SlashEvent = knife:WaitForChild("SlashEvent")

local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local humanoid = Character:WaitForChild("Humanoid")

local slash = script:WaitForChild("Slash")
local animTrack = humanoid:WaitForChild("Animator"):LoadAnimation(slash)
local debounce = false

knife.Activated:Connect(function()
	if not debounce then
		debounce = true	
                SlashEvent:FireServer()	
		animTrack:Play()
		task.wait(2)
		debounce = false
	end
end)

Server script (also in tool)

local Event = Instance.new("RemoteEvent", script.Parent)
Event.Name = "SlashEvent"
local Handle = script.Parent:WaitForChild("Handle")

local function Damage(Player, Humanoid)

				Humanoid:TakeDamage(40)
if Humanoid.Health == 0 then
						Player.leaderstats.Coins.Value += 10
						Player.leaderstats.Kills.Value += 1
						
					end
end

Event.OnServerEvent:Connect(function(Player)
    local h = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
    if not h then
        return
    end
    for i, v in pairs(workspace:GetPartsBoundInBox(Handle.CFrame, Handle.Size)) do
        local l = v.Parent:FindFirstChildOfClass("Humanoid")
        if v and l and l ~= h then
            Damage(Player, l)
    end
end)

Thanks for your help! I’ll try that out and see any changes.