Camera Recoil Effect

I have been wondering how I would make a camera kickup script that looks smooth. I have attempted to tween the camera but it has only resulted in the camera zooming in and out whenever the tween was played.

Sample of how I made the code:

local TweenService = game:GetService("TweenService")
local camera = workspace.CurrentCamera

local tweenInfo = TweenInfo.new(0.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out, 0, true, 0)
local goal = {}

goal.CFrame = camera.CFrame * CFrame.Angles(math.rad(3), 0, 0)

local tween = TweenService:Create(camera, tweeninfo, goal)
tween:Play()

I have also attempted to use basic CFrame multiplication but it ends up feeling too rigid. Does anyone have any ideas on how I could make a smooth camera recoil script?

2 Likes

I once made a recoil script myself.

	spawn(function()
		game["Run Service"].RenderStepped:Wait()
		local randomy = (math.random(0,strengthy*2)-strengthy)/1200
		
		if game.Workspace.CurrentCamera.CFrame.LookVector.Y < 0.9 then
			game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame*CFrame.Angles(strengthx/360/2,randomy/4,0)
			game["Run Service"].RenderStepped:Wait()
			game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame*CFrame.Angles(strengthx/360/2,randomy/4,0)
		else
			game["Run Service"].RenderStepped:Wait()
		end
		
		local value = 0
		for i=20,1,-1 do
			game["Run Service"].RenderStepped:Wait()
			game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame*CFrame.Angles(-strengthx/7200*i/14,randomy/40*i/10,0)
			value = value + i/10
		end
		--print(value)
	end)
	
	return true
end

strengthx is the strength to the left and right and strengthy is up/down. Feel free to modify

5 Likes

I have also tried making a camera recoil effect using TweenService, but that caused various problems, including the fact that the camera would be stuck in place when the tween played. My approach to this was to manually “simulate” the tween with a custom function.

This is what I attempted (I havn’t added recoil recovery yet though):

local function recoil()
	local magnitude = recoilstats.Magnitude
	--use magnitude = average*framecount
	local numberofframes = recoilstats.Time*30 --run at 30 fps
	local maxchange = magnitude/numberofframes*2
	--minchange is always 0,0,0
	for a = numberofframes,1,-1 do
		local change = maxchange*((a-1)/(numberofframes-1))
		camera.CFrame = camera.CFrame*CFrame.Angles(change.x,change.y,change.z)
		wait(1/30)
	end
end
5 Likes

Can you provide a video/gif of it

Sorry for the low video quality, and the weapon isn’t animated either. But the recoil script works and simulates a quadratic tween.

Note: the script I posted earlier does not include recoil recovery, however, it should be easy to implement using the same concept as I did for the recoil.

2 Likes

I would make recoil only when the gun is aimed and do spread when its not like Phantom Forces you can say

I would make recoil only when the gun is aimed

Guns should have recoil regardless of whether it is aimed. But everyone makes their weapon mechanics differently so feel free to change whatever you want. And I did incorporate spread because as you can see, the recoil pattern isn’t completely consistent.

Im having trouble figuring out how you did the recoil recovery. Could you explain a little?

I need help on the retreat too! Suppose in a rifle, if a player burst out a lot of bullets, how would I retreat them back to where they started the burst?