Creating a swinging weapon to only fire when properly swung at an object?

local tool = script.Parent

local handle = tool:WaitForChild('Handle')

local cooldown = 0.25
local swinging = false

tool.Activated:Connect(function()
	handle.Touched:Connect(function(hit)
		if swinging then
			print(hit)
			swinging = false
		end
		wait(0.1)
		swinging = true
	end)
end)

I’m trying to create a sword that would only do damage (eventually) when it’s actually been swung and used. I’ve tried multiple ways, all just resulting in it either printing when it’s just touching a part, clicking and then walking over to a part and it printing, etc. I want them to have to click, and check if the tool is touching something. If not, cancel everything basically, until it is clicked again. Atm, all I have to do is click once, walk over to a part and touch it and it starts printing.

1 Like

Try this mate.
Previously - every time you ‘swung’ or activated the sword - it was creating a new Touch event - which will be bad over time. You need to separate the two events.

[EDIT]
As Darkmist101 says;

local tool = script.Parent

local handle = tool:WaitForChild('Handle')

local cooldown = 0.25
local swinging = false

tool.Activated:Connect(function()
	wait(0.1)
	swinging = true
	wait(0.25)
	swinging = false
end)

handle.Touched:Connect(function(hit)
	if swinging then
		print(hit)
		swinging = false
	end
end)
2 Likes

New problem of clicking away from a part, then moving and touching the part after I have clicked still shows a print

1 Like

You need to set swinging to false outside of touched as well, you only turn it off when it hits something.

3 Likes
local tool = script.Parent

local handle = tool:WaitForChild('Handle')

local cooldown = 0.25
local swinging = false

tool.Activated:Connect(function()
	handle.Touched:Connect(function(hit)
		if swinging then
			swinging = false
			print(hit)
		end
		wait(cooldown)
		swinging = true
	end)
	swinging = false
	wait(cooldown)
end)

Still doesnt work

1 Like

I would use tick and wait instead of just wait. Here’s an example below

local Swung = false
local Tick = tick()
tool.Activated:Connect(function()
	if tick() - Tick >= cooldown then
		Tick = tick()
		Swung = true
		wait(cooldown)
		Swung = false
	end
end
2 Likes

The issue there appears to be that swinging is made false instantly. In my code I also made a few other changes with explanations.

tool.Activated:Connect(function()
    if swinging then return end -- Debounce to stop player spamming swings
    swinging = true -- Set swinging to true so you can actually do anything in the touched event

    wait(cooldown)

    -- This if block is overkill in this case but it's good practice when working with more complex 'swinging' states
    if swinging then -- Stop swinging if it is still swinging
        swinging = false 
    end
end)

-- You want to do this outside of the activated function because you'll need to :Disconnect() it if you call it in there
handle.Touched:Connect(function(hit)
    if swinging then
        swinging = false
        print(hit)
    end
end)
2 Likes