Double clicking does not call UserInputService.InputEnded on the second click

I made a gun script that allows for automatic fire. The issue is, double clicking with it will cause it to not stop firing until you click a few times or hold the mouse down again (or unequip the weapon).

The part this local script is about starts at ‘FireDebounce’

Tool = script.Parent
Handle = Tool:WaitForChild("Handle")
AmmoType = Tool.Stats.Ammo.Value

Character = Tool.Parent
Player = game:GetService('Players').LocalPlayer
Humanoid = Character:FindFirstChildOfClass("Humanoid")
Animator = Humanoid:WaitForChild('Animator')

Mouse = Player:GetMouse()

localfiring = false

local ReplicatedStorage = game:GetService('ReplicatedStorage')
local FireRE = ReplicatedStorage.Guns.Firing

local UserInputService = game:GetService('UserInputService')

local ToolAnimations = {
	Equip = Animator:LoadAnimation(Tool.Animations.Equip),
	Moving = Animator:LoadAnimation(Tool.Animations.Moving),
	Shooting = Animator:LoadAnimation(Tool.Animations.Shooting),
}

function MovementBob()
	if not Tool.Enabled then
		return
	end

	ToolAnimations.Moving:AdjustSpeed(Humanoid.MoveDirection.Magnitude)

end

function Equipped()

	for i, v in Animator:GetPlayingAnimationTracks() do
		if v.Name == 'ToolNoneAnim' then
			v:Stop()
		end
	end
	
	ToolAnimations.Equip:Play()

	repeat task.wait() until Tool.Enabled == true

	ToolAnimations.Moving:Play()

end

function Unequipped()
	
	localfiring = false
	
	for i, v in Animator:GetPlayingAnimationTracks() do
		for x, c in ToolAnimations do
			if v.Name == c.Name then
				v:Stop()
			end
		end
	end
end

FireDebounce = false

function Fire()
	
	if not Tool.Enabled then
		repeat task.wait() until Tool.Enabled == true
		if FireDebounce == true then return end
	end
	
	localfiring = true
	
	while localfiring == true and Character.Ammo[AmmoType].Value >= 1 do
		
		FireDebounce = true
		
		ToolAnimations.Shooting:Play()
	
		FireRE:FireServer(workspace.CurrentCamera.CFrame.Position, Mouse.Hit.Position)
		
		task.wait(0.1)
		
		ToolAnimations.Shooting:Stop()
		
		repeat task.wait() until Tool.Firing.Value == false
		
		FireDebounce = false
	
	end
	
end

function StopFire()
	
	localfiring = false

end

Tool.Unequipped:Connect(Unequipped)
Tool.Equipped:Connect(Equipped)

Mouse.Button1Down:Connect(Fire)

UserInputService.InputEnded:Connect(function(object)
	if object.UserInputType == Enum.UserInputType.MouseButton1 then
		StopFire()
	end
end)

game:GetService('RunService').RenderStepped:Connect(MovementBob)

Server script also:

Tool = script.Parent
Handle = Tool.Handle
Firerate = Tool.Stats.Firerate.Value
Damage = math.random(Tool.Stats.Damage.Value.x, Tool.Stats.Damage.Value.y)
AmmoType = Tool.Stats.Ammo.Value

local ReplicatedStorage = game:GetService('ReplicatedStorage')
local FireRE = ReplicatedStorage.Guns.Firing
local UpdateAmmoHud = ReplicatedStorage.Guns.UpdateAmmoHud

local CollectionService = game:GetService('CollectionService')

local ToolAnimations = {
	Equip = Tool.Animations.Equip,
	Moving = Tool.Animations.Moving,
	Shooting = Tool.Animations.Shooting,	
}

function Equipped()
	
	Tool.Enabled = false
	Tool.Firing.Value = false
	
	Character = Tool.Parent
	Player = game:GetService('Players'):GetPlayerFromCharacter(Character)
	Humanoid = Character:FindFirstChildOfClass("Humanoid")
	Animator = Humanoid:WaitForChild('Animator')
	
	UpdateAmmoHud:FireClient(Player, AmmoType)
	
	Handle.equip:Play()
	
	Tool.ToolLocal.Enabled = true

	task.wait(Animator:LoadAnimation(ToolAnimations.Equip).Length)
	
	Tool.Enabled = true

end

function Unequipped()
	
	UpdateAmmoHud:FireClient(Player, AmmoType)

	Tool.Enabled = false
	Tool.Firing.Value = false
	
	Tool.ToolLocal.Enabled = false

end

FireRE.OnServerEvent:Connect(function(Player, CameraPos, MousePos)
	
	if Player == game.Players:GetPlayerFromCharacter(Tool.Parent) then
		
		if Player.Character:WaitForChild('Ammo')[AmmoType].Value <= 0 then return end
		
		Damage = math.random(Tool.Stats.Damage.Value.x, Tool.Stats.Damage.Value.y)
		
		Player.Character.Ammo[AmmoType].Value -= 1
		
		UpdateAmmoHud:FireClient(Player, AmmoType)

		Tool.Enabled  = false
		Tool.Firing.Value = true
		
		local FireSound = Tool.Sounds.fire:Clone()
		FireSound.Parent = Handle
		FireSound:Play()
		
		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {Tool.Parent:GetDescendants(), CollectionService:GetTagged('Invis'), CollectionService:GetTagged('Effects')}
		raycastParams.FilterType = Enum.RaycastFilterType.Exclude
		raycastParams.IgnoreWater = true
		
		local raycast = workspace:Raycast(CameraPos, (MousePos - CameraPos)  * 1.5 , raycastParams)
		
		if raycast ~= nil then
			local touchedPart = raycast.Instance
			if touchedPart ~= nil then
					if touchedPart:FindFirstAncestorOfClass("Model") then --Makes hats and other things not eat damage
					local model = touchedPart:FindFirstAncestorOfClass("Model")
					local hum = model:FindFirstChildOfClass("Humanoid")
					if hum then
						hum:TakeDamage(Damage)
					end
				else --bullet smoke looked weird on enemies
					local Bullet = ReplicatedStorage.Guns.Bullet:Clone()
					Bullet.Parent = workspace
					Bullet.Position = MousePos
					Bullet.SelfDestruct.Enabled = true
				end
			end
		end
		
		task.spawn(function()
			task.wait(FireSound.TimeLength)
			FireSound:Destroy()
		end)
		
		task.wait(Firerate)
		
		Tool.Enabled = true
		Tool.Firing.Value = false
		
	end
	
end)

Tool.Unequipped:Connect(Unequipped)
Tool.Equipped:Connect(Equipped)
1 Like

can you try and see if this works?

Mouse.Button1Up:Connect(StopFire)

replace your InputEnded with it.

I used InputEnded becausue I was having the same problem with Mouse.Button1Up and saw a forum post that said it was a solution. It was not.

interesting… what about replacing the button1down with UIS InputBegan?

sorry, maybe im just not seeing the issue, i just woke up lol

okay so i just tested a similar code and i could not reproduce the issue youre having:

local uis = game:GetService("UserInputService")
local players = game:GetService("Players")
local player = players.LocalPlayer
local mouse = player:GetMouse()

local firing = false

mouse.Button1Down:Connect(function()
	firing = true
	while firing do
		print("Firing")
		task.wait(0.4)
	end
end)

uis.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		firing = false
	end
end)

worked just fine, even with very fast double clicks.

This is a very odd problem bc after reading your code, it doesn’t look like it should be doing that. Can you use some print statements to debug? Print out localfiring and any other variable for the events to see what happens

copied and modified ur script, this works fine as well:

local UserInputService = game:GetService('UserInputService')
local player = game:GetService("Players").LocalPlayer
local Mouse = player:GetMouse()
local localfiring = false
local FireDebounce = false

function Fire()

	if FireDebounce == true then return end

	localfiring = true

	while localfiring == true do

		FireDebounce = true
		print("Firing")
		--ToolAnimations.Shooting:Play(
		--FireRE:FireServer(workspace.CurrentCamera.CFrame.Position, Mouse.Hit.Position)
		task.wait(0.1)
		--ToolAnimations.Shooting:Stop()
		--repeat task.wait() until Tool.Firing.Value == false
		FireDebounce = false
	end
end

function StopFire()
	localfiring = false
end

Mouse.Button1Down:Connect(Fire)

UserInputService.InputEnded:Connect(function(object)
	if object.UserInputType == Enum.UserInputType.MouseButton1 then
		StopFire()
	end
end)

for firing an automatic weapon, you can do UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) in the condition of your while loop, that way the gun will stop firing if LMB is released

it will replace your StopFire function and will also remove the localFiring boolean
you can actually see the logic i’m using if you’re confused

          local function Fire()
			utility.AnimateViewmodel(gun, viewmodel, 'shoot')
			PlaySound(gun, 'Shoot')
			if gunData.gunType ~= 'shotgun' and not gun:GetAttribute('Aiming') then
				--direction = GetHipfireSpread(hipfireSpread, direction)
			end
			
			if tracersEnabled and gunData.gunType ~= 'shotgun' then
				Tracer(gun, gunData, direction)
			end
			
			ApplyRecoil(recoilStrength)
			task.spawn(function()
				effectParts.FlashPart.FlashImage:Emit(1)
				effectParts.FlashPart.Light.Enabled = true
				task.wait(0.1)
				effectParts.FlashPart.Light.Enabled = false
			end)
			
			local raycast = Raycast(origin, direction, gunData)
			local hitPos			
			if raycast then
				hitPos = raycast.Position
			end
			
			shoot:FireServer(origin, aimPos, direction, gunData.maxDistance, hitPos)
		end
		
		if gunData.gunType == 'semi' then
			if fireBlocked then return end
			fireBlocked = true
			task.delay(firerate, function()
				fireBlocked = false
			end)
			
			Fire()
		elseif gunData.gunType == 'auto' then
			while uInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) and gun.Bullets.Value > 0 do
				Fire()
				task.wait(firerate)
			end
		end
1 Like

wouldnt that not respond to quick clicks? (single fires)

nope, it actually kind of… does this

i never really bothered fixing this because this issue is only present in automatics, and automatics are already fast

i always assumed it’s just an error in how i call the logic, and how i don’t check if the weapon is firing already (because the way i set the weapon’s firing state is a bit inconsistent, which allows the player to rapid fire

but i found this to be a lot more consistent

from what im seeing its firing multiple times at once right?
if so then thats def fixable.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.