How can I make this firing CFrame animation more smooth?

https://gyazo.com/092a5eb01a9758fb4caa281ae0cf4217
^^ What I currently have

--- fps by vf9r (tutorial by other yt)

local plr = game.Players.LocalPlayer
local char = game.Players.LocalPlayer.Character
local camera = workspace.CurrentCamera

local runs = game:GetService("RunService")
local uis = game:GetService("UserInputService")
local rs = game.ReplicatedStorage

local aiming = false
local leanstate = 0

local main = CFrame.new()
local gunModel
local data
local cameraMain = CFrame.new()

local guns = require(rs.Guns)
local currentGun

local firing = false
local gunChosen = false



uis.InputBegan:Connect(function(input,process)
	if not process then
		
		if input.UserInputType == Enum.UserInputType.MouseButton2 then
			aiming = true
		end
		
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			firing = true
		end
		
		if input.KeyCode == Enum.KeyCode.Q then
			leanstate = 1
		end
		
		if input.KeyCode == Enum.KeyCode.E then
			leanstate = 2
		end
		
		if input.KeyCode == Enum.KeyCode.One then
			if gunChosen == false then
				currentGun = guns.list[1]
				print("changed current gun to "..currentGun)
				gunModel = rs:FindFirstChild(currentGun):Clone()
				data = require(rs:FindFirstChild(currentGun.."Module"))
				gunChosen = true
			end
		end

		if input.KeyCode == Enum.KeyCode.Two then
			if gunChosen == false then
				currentGun = guns.list[2]
				print("changed current gun to "..currentGun)
				gunModel = rs:FindFirstChild(currentGun):Clone()
				data = require(rs:FindFirstChild(currentGun.."Module"))
				gunChosen = true
			end

		end
		
	end
end)

uis.InputEnded:Connect(function(input,process)
	if not process then
		
		if input.UserInputType == Enum.UserInputType.MouseButton2 then
			aiming = false
		end
		
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			firing = false
		end
		
		
		if input.KeyCode == Enum.KeyCode.Q then
			leanstate = 0
		end

		if input.KeyCode == Enum.KeyCode.E then
			leanstate = 0
		end

	end
end)

repeat wait() until gunChosen == true

for i,parts in pairs(gunModel:GetChildren()) do
	gunModel.Anchored = true
	gunModel.CanCollide = true
	parts.Anchored = true
	parts.CanCollide = true

	local gunWeld = Instance.new("Weld",parts)

	gunWeld.Part0 = gunModel
	gunWeld.Part1 = parts

	gunWeld.C1 = parts.CFrame:inverse()*gunModel.CFrame

	gunModel.Anchored = true
	gunModel.CanCollide = false
	parts.Anchored = false
	parts.CanCollide = false

	gunModel.Parent = camera
end

runs.RenderStepped:Connect(function()
	
	gunModel.CFrame = camera.CFrame*main
	main = main:lerp(CFrame.new(),.1)
	cameraMain = cameraMain:lerp(CFrame.new(),.1)
	camera.CFrame = camera.CFrame*cameraMain
	
	if firing == true then -- this is where the animation comes in
		main = main:lerp(CFrame.new(-1,0,0),.1)
		wait(.1)
		main = CFrame.new()
	end	
	
	if leanstate == 1 then
		main = main:lerp(main*CFrame.new(-2,0,0)*CFrame.Angles(0,0,math.rad(30)),.1)
		cameraMain = cameraMain:lerp(CFrame.new(-2,0,0)*CFrame.Angles(0,0,math.rad(-5)),.1)
	end
	
	if leanstate == 2 then
		main = main:lerp(main*CFrame.new(2,0,0)*CFrame.Angles(0,0,math.rad(-30)),.1)
		cameraMain = cameraMain:lerp(CFrame.new(2,0,0)*CFrame.Angles(0,0,math.rad(5)),.1)
	end
	
	if aiming then
		main = main:lerp(data.ads,.1)
	else
		main = main:lerp(data.main,.1)
	end
	
end)

What I am using ^^

How can I make it so its more smooth and not so frantic? I only want it to bounce forward and then come back like normal recoil works like.

1 Like

Using TweenService will probably be your best bet!

Placebo code similar to what you want:

local TweenService = game:GetService("TweenService")

if firing == true then
    local mainCFrame = TweenService:Create(InsertWhatYouWantToAnimateHere, TweenInfo.new(InsertAmountOfTimeHere), {CFrame = CFrame.new(-1,0,0)})
    mainCFrame:Play()
end

I would provide a better example. However, I’m not familiar with lerp, so I’m not too sure what exact objects you want to Tween :sweat_smile: