Holding left mouse button right after letting go initially does nothing

  1. What do you want to achieve? Keep it simple and clear!
    I am trying to get my tool to be able to hold click to deal damage, even when i hold click again right after letting go.

  2. What is the issue? Include screenshots / videos if possible!
    It works fine when I hold click the first time, however, when I let go and try to hold the mouse button again, nothing happens. I have to start holding click after the cooldown.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Tried looking around developer forums, moving debounces. I feel like I’m doing something wrong on accident that’s a simple mistake, but I can’t tell what it is.

local equipped = false
local held = false
local onCD = false
local click = false


tool.Equipped:Connect(function()
	equipped = true
	
	mouse.Button1Down:Connect(function()
		if click == false then
			click = true
			held = true
			while held == true and equipped == true do
				if onCD == false then
					onCD = true
					sfx.equip:Stop()
					sfx.click:Play()

					--creating size of hitbox
					local size = Vector3.new(2,2,2)

					--Cframe Position
					local root = player.character.HumanoidRootPart
					local Cframe = root.CFrame - root.CFrame.ZVector * 2 - root.CFrame.YVector * 1

					remote:FireServer(size, Cframe, damage)
					onCD = false
					task.wait(.5)
				end
			end
			click = false
		end
	end)
	
	mouse.Button1Up:Connect(function()
		held = false
	end)
	
end)
4 Likes

The problem is the task. Wait(.5) So you hold click, release and click again. If you click again when the task is waiting it does not register the click.

2 Likes

Where should I put the cooldown then or what is an option to fix it? I’m not looking to be spoon fed, but I can’t find another way to do this.

2 Likes

Had to move it out from Tool.Equipped, please try:

local function handleDamage()
	if not onCD then
		onCD = true
		sfx.equip:Stop()
		sfx.click:Play()

		--creating size of hitbox
		local size = Vector3.new(2, 2, 2)

		--Cframe Position
		local root = player.Character.HumanoidRootPart
		local Cframe = root.CFrame - root.CFrame.ZVector * 2 - root.CFrame.YVector * 1

		remote:FireServer(size, Cframe, damage)
		print("damage")
		onCD = false
		task.wait(0.5)
	end
end

tool.Equipped:Connect(function()
	equipped = true
	local mouseDown
	mouseDown = mouse.Button1Down:Connect(function()
		if not click then
			click = true
			held = true
			while held and equipped do
				handleDamage()
				task.wait()
			end
			click = false
		end
	end)

	local mouseUp
	mouseUp = mouse.Button1Up:Connect(function()
		held = false
	end)

	tool.Unequipped:Connect(function()
		equipped = false
		mouseDown:Disconnect()
		mouseUp:Disconnect()
	end)
end)
2 Likes

That also doesn’t work. Should I just try reconstructing it from the ground up instead or something?

2 Likes

You are right. I was clicking too slowly.

2 Likes

That was hard to fix. Thanks for the challenge. Had to time tick() the crap of me.

Just dumping my debug code you need to adapt to your code.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local tool = Instance.new("Tool")

tool.Name = "MyTool"
tool.RequiresHandle = false
tool.Parent = game.Players.LocalPlayer.Backpack

local damageActive = false
local equipped = false
local held = false
local onCD = false
local click = false

local startTime 
local intervalsPassed = 0 

local function handleDamage(theTime)
	local timeCheck  = 0.5 * intervalsPassed
	if not onCD and theTime >= timeCheck then
		onCD = true
		--sfx.equip:Stop()
		--sfx.click:Play()

		--creating size of hitbox
		local size = Vector3.new(2, 2, 2)

		--Cframe Position
		local root = player.Character.HumanoidRootPart
		local Cframe = root.CFrame - root.CFrame.ZVector * 2 - root.CFrame.YVector * 1

		--remote:FireServer(size, Cframe, damage)
		--print(theTime)
		print("damage")
		onCD = false
		--task.wait(0.5)
		intervalsPassed = intervalsPassed + 1
	end
end

tool.Equipped:Connect(function()
	equipped = true
	local mouseDown
	mouseDown = mouse.Button1Down:Connect(function()
		if not click then
			click = true
			held = true
			startTime = tick()
			while held and equipped do				 
				handleDamage(tick() - startTime)
				task.wait()
			end
			startTime = 0
			intervalsPassed = 0 
			click = false
		end
	end)

	local mouseUp
	mouseUp = mouse.Button1Up:Connect(function()
		held = false
	end)

	tool.Unequipped:Connect(function()
		equipped = false
		mouseDown:Disconnect()
		mouseUp:Disconnect()
	end)
end)
2 Likes

It works, kind of. But now I can spam click instead which is not what I want either.
And on top of that, ticks are kind of confusing to me.

1 Like

So you are saying that you don’t want the ability to spam click but you can hold the left mouse button?

In that case, I suggest you see how long the player has held the mouse. If it is less than your cooldown timer then use task.wait(cooldown) if it is equal or greater than the cooldown then you do not use the wait.

I would provide code but due to being on mobile I can’t. :p

1 Like

Your debounce does not work because of this line. The function is fired every time that the player presses down left click on his mouse, so the function is fired nevertheless.

mouse.Button1Down:Connect(function()

And as for the script, do this instead:

local UIS = game:GetService("UserInputService")
local held = false

UIS.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		held = true
		while held == true do
			"the script here"
			game:GetService("RunService").RenderStepped:Wait()
		end
	end
end)

UIS.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		held = false
	end
end)
1 Like

Ok, no tick() but this time os.clock() just to guarantee no damage will be done util 0.5 has been passed.

local damageActive = false
local equipped = false
local held = false
local onCD = false
local click = false

local lastDamageTime = os.clock()

local function handleDamage()	

	local currentTime = os.clock()
	
	if not onCD and currentTime - lastDamageTime >= 0.5 then
		onCD = true
		--sfx.equip:Stop()
		--sfx.click:Play()

		--creating size of hitbox
		local size = Vector3.new(2, 2, 2)

		--Cframe Position
		local root = player.Character.HumanoidRootPart
		local Cframe = root.CFrame - root.CFrame.ZVector * 2 - root.CFrame.YVector * 1

		--remote:FireServer(size, Cframe, damage)
		print("damage")
		onCD = false
		lastDamageTime = currentTime
	end
end

tool.Equipped:Connect(function()
	equipped = true
	local mouseDown
	mouseDown = mouse.Button1Down:Connect(function()
		if not click then
			click = true
			held = true
			while held and equipped do				 
				handleDamage()
				task.wait()
			end
			click = false
		end
	end)

	local mouseUp
	mouseUp = mouse.Button1Up:Connect(function()
		held = false
	end)

	tool.Unequipped:Connect(function()
		equipped = false
		mouseDown:Disconnect()
		mouseUp:Disconnect()
	end)
end)

You have various redundancies in your code. If you’re using server-based debounce, then continue to do so until the end. This is the updated code:

local lastDamageTime = os.clock()
local function handleDamage()

    local currentTime = os.clock()

    if not currentTime - lastDamageTime >= 0.5 then 
       return 
    end

    LastDamageTime = currentTime
end

Please do not be haughty while on forums. We are here to help one another and not to make jests about each other. There is always a mirror if you wish to see a circus.

It is not server-side, it is not a debounce, I do not know if the check onCD is redundant as it is not my code. I am only here to help with no intention of being haughty.