How to make a gun recoil

Hi,
I’ve been trying to add a gun recoil to my guns. But it breaks whenever you spam the left mouse button, it is multiplying the recoil onto itself and doesn’t stop. Does anybody know how to fix it or a better way of doing it? (I’m not asking for a complex recoil it’s just a simple camera wobble)

current code:

mouse.Button1Down:Connect(function()

	-- checks if the tool is equipped --
	if equipped == true then
		
		if shooting == false then
			
			-- checks if cooldown is over and there's ammo in mag --
			if cooldown == false and magazineSize > 0 then
				
				if automatic == true then

					shooting = true
					changePlrValue:FireServer("shooting", true)

					while shooting == true do

						-- checks if mag size is 0 --
						if magazineSize == 0 then

							gunState("No ammo")

						else
							
							cooldown = true
							-- set gunState to "Ready" --
							gunState("Ready")

							-- fire server that the bullet was shot --
							script.Parent.Fire:FireServer(mouse.Hit.p)

							magazineSize -= 1 -- take one bullet from mag

							-- set gunAmmo to current ammo out of mag size
							gunAmmo()

							-- recoil --
							Connection = RunService.RenderStepped:Connect(playRecoil)
							wait(recoilTime)
							Connection:Disconnect()
							
							-- wait fire cooldown --
							wait(fireCooldown)
							cooldown = false

						end
						wait(0.01)
					end

				end

(if the there’s not enough end’s it’s because I cut the code out)

recoil functions:

local function recoverRecoil()
	
	Camera.CFrame = Camera.CFrame:Lerp(Camera.CFrame * CFrame.Angles(math.rad(-recoilHeight), 0, 0), incrementTime)
	
end

-- do camera recoil --
local function playRecoil()
	
	local TotalSpeed = speedShake * tick()
	local bobbleX = math.cos(TotalSpeed * distanceShake)
	local bobbleY = math.abs(math.sin(TotalSpeed) * distanceShake)
	
	Camera.CFrame = Camera.CFrame:Lerp(Camera.CFrame * CFrame.new(bobbleX, bobbleY, 0) * CFrame.Angles(math.rad(recoilHeight), 0, 0), incrementTime)
	
end

Thanks!

4 Likes

Would it be that you don’t have the cooldown set to false in the if statement of this loop?

				while shooting == true do

Try changing

							-- wait fire cooldown --
							wait(fireCooldown)
							cooldown = false

						end

to

							-- wait fire cooldown --
							wait(fireCooldown)
						end
						cooldown = false
2 Likes

Thanks for replying, I tried it but still no luck. The problem has to be with the recoil because it works fine until I spam left mouse button and recoil isn’t stopping no matter what and it’s getting stringer every click.

Can a Lerp be interrupted? I’m not too familiar with them.
It looks like you have incrementTime in the Lerp statement for the amount of time the Lerp has to move the parts, but if the function gets called again then you are Lerping again.
What if you put a wait(incrementTime) after each Lerp statement?

1 Like

Thanks, I will try this right now. I’m not familiar with Lerp too, I got it from some recoil tutorial.

Yay it works! Thanks a lot man, I really didn’t understand the issue.
That’s how I put it:

-- recoil --
Connection = RunService.RenderStepped:Connect(playRecoil)
local rT = recoilTime
wait(recoilTime)
Connection:Disconnect()
wait(incrementTime)

What’s happening is when you click the left mouse button the firing function starts and the recoil function gets called, but the recoil function just runs the lerp. The lerp runs, but if you spam the button then it runs again, starting the movement over when it’s part way done.
When you add the wait in the recoil section it waits for the lerp to run the same amount of time and then allows it to start again at the beginning.

1 Like