UserInputService firing twice(even with debounces

I made a modular gun system using modulescripts, etc. the localscript thats inside the guns when you press 1 it works normal the first time and just prints “1 is pressed” once, but then after that it always fires twice, unequipping then reequipping immediately. i have tried multiple types of debounces and task.wait’s and cannot seem to get anything to work.

image
in the image above the first two prints are how they should, the ones after all happened immediately.

I have seen similiar posts on the forums and ive tried all of their solutions and none worked.

uis.InputBegan:Connect(function(input, gameProccessed)
	if gameProccessed then return end
	if input.KeyCode == Enum.KeyCode.One then
		
		print("1 is pressed")
		
		GunModule.Equip("StarterSmg", game.Players.LocalPlayer.Character)
		
	end
end)

this is the localscript code in the gun, here is the modulescript functions.

function GunModule.Equip(gunName, character)

	local player = game.Players:GetPlayerFromCharacter(character)
	local hum = character:FindFirstChild("Humanoid")

	-- If gun is already equipped, unequip it first
	if GunModule.gunEquipped then
		print("Unequipping current gun")
		GunModule.Unequipped(gunName, character)
		return
	end
	-- Find tool in backpack
	local tool = player.Backpack:FindFirstChild(gunName)
	if not tool then
		print("Tool not found in backpack")
	end

	if tool then
		print("Equipping tool:", tool.Name)
		GunModule.gunEquipped = true
		GunModule.canShoot = true
		hum:EquipTool(tool)
		CrosshairModule.Enable()
		CrosshairModule.Reset()
	else
	end

	-- Play Equip & Idle Animations
	local gunAnims = AnimTable[gunName]
	if gunAnims then
		if gunAnims.equip then
			playAnimation(character, gunAnims.equip, "equip")
		end
		if gunAnims.idle then
			playAnimation(character, gunAnims.idle, "idle")
		end
	end

end




function GunModule.Unequipped(gunName, character)
	if not GunModule.gunEquipped then
		print("Gun is already unequipped")
		return
	end
	print("Unequipping...", gunName)
	
	local player = game.Players:GetPlayerFromCharacter(character)
	local hum = character:FindFirstChild("Humanoid")
	hum:UnequipTools()
	GunModule.gunEquipped = false


	-- Stop Animations
	local gunAnims = AnimTable[gunName]
	if gunAnims then
		if gunAnims.unequip then
			playAnimation(character, gunAnims.unequip, "unequip")
		end
		if gunAnims.idle then
			stopAnimation("idle")
		end
	end

	-- Disable Ammo UI
	local gui = player.PlayerGui:FindFirstChild("AmmoGui")
	if gui then
		gui.Enabled = false
	end

	-- Prevent shooting while unequipped
	GunModule.canShoot = false
	CrosshairModule.Disable()

	-- Wait briefly before forcing unequip
	task.wait(0.1)
	hum:UnequipTools()

	-- Double check that tool is in backpack
	if not player.Backpack:FindFirstChild(gunName) then
		warn("WARNING: Tool still missing after unequip! Potential deletion issue.")
	end
end
1 Like

This issue is likely due to GunModule.Equip calling GunModule.Unequipped, which unequips the gun and returns immediately without setting gunEquipped back to false before reattempting to equip.
I’m just going to base my guess on that. This may work for you.

Untested …

function GunModule.Equip(gunName, character)
	local player = game.Players:GetPlayerFromCharacter(character)
	local hum = character:FindFirstChild("Humanoid")

	if GunModule.gunEquipped then
		GunModule.Unequipped(gunName, character)
		task.wait(0.1)
		GunModule.gunEquipped = false
	end

	local tool = player.Backpack:FindFirstChild(gunName)
	if not tool then return end

	GunModule.gunEquipped = true
	GunModule.canShoot = true
	hum:EquipTool(tool)
	CrosshairModule.Enable()
	CrosshairModule.Reset()

	local gunAnims = AnimTable[gunName]
	if gunAnims then
		if gunAnims.equip then playAnimation(character, gunAnims.equip, "equip") end
		if gunAnims.idle then playAnimation(character, gunAnims.idle, "idle") end
	end
end

I just tried that and it still prints one is pressed twice when i try to unequip and immediately re equips it. Thank you for your feedback though

1 Like

hmm, maybe the tool equips by the built in functions (when pressing 1) and then your localscript sees that its not in the backpack and unequips the tool?

i have this is
starterplayerscripts game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.All, false)

so it shouldnt

wait, arent tools supposted to be equipped via the server? sorry if im wrong here.

uis.InputBegan:Connect(function(input, gameProccessed)

Is this somehow running twice? If so, then you’re gonna have two active connections which are running the same code. One will unequip the weapon, and the next one will re-equip it

i added a print right after that line and yes it runs twice, but only after i press 1 once to equip it, it doesnt start running twice until after its equipped

So then that’s your issue right? You have two active connections whose callbacks are calling GunModule.Equip one right after the other?

Well that’s too bad … to be honest I don’t trust this:
uis.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed or debounce then return end

Do this with a db (just to test this)

local db=true
if db then db=false

 GunModule.Equip("StarterSmg", game.Players.LocalPlayer.Character)

 task.wait(whatever works here)
 db=true
end

I know gameProcessed works with GUI icons but, I’ve never used it as a direct de-bounce other than that.

edit** i thought wrong, it kinda works

after i equip once it equips properly, but then i press 1 again it does what it has been doing, but if i press it a third time it unequips properly. but then when i restart the test it will sometimes work without it running twice. so its 50/50 for it to work properly, or kinda properly


local db = false
uis.InputBegan:Connect(function(input, gameProccessed)
	if gameProccessed or db then return end
	if input.KeyCode == Enum.KeyCode.One then
		if not db then
			db = true
			print("equipped")
			GunModule.Equip(gunName, character)
			task.wait(1)
			db = false
		end
	end
end)
```

This is the problem … need to find a way to do that.

the problem is something to do with the uis.inputbegan function becuase i have it like this:

local db = false
uis.InputBegan:Connect(function(input, gameProccessed)
	if gameProccessed or db then return end
	if input.KeyCode == Enum.KeyCode.One then
		if not db then
			db = true
			print("equipped")
			GunModule.Equip(gunName, character)
			task.wait(1)
			db = false
		end
	end
end)

and it will print “1” after i equip it the first time, then when i press 1 to unequip it I get “1” printed twice with just one press of the button, it works perfectly with a task.wait(3) but anything below 3 seconds makes it bug out, i am not sure how this is happening.

–Edit: I forgot to add. For some reason also when i have the task.wait(3) for 3 seconds, i can instantly un equip after equipping which i shouldnt be able to do because of the wait. but no matter what i have to wait for 3 seconds to equip it again

This isn’t needed. That is totally covered with the db.
You’re using InputBegan So, why not add a InputEnded to reset what needs to be.

So i am not sure why this wasnt working how i had it, but i switched the gunequipped logic to the userinputservice function and it fixed it completely, thank you everyone for the feedback

-Edit, okay i noticed it started happening again and it was because the script kept being cloned over and over again every single time i equipped and unequipped the tool. so it kept running multiple instances of the same local script completely bugging out everything. so it fix it i took this script out and put it into starterplayer.

also, i recommend you look into CAS (contextactionservice). its a pretty handy tool when you want to disable and enable functions connected to inputs.

i definitely will now, thank you