How To Make A Realistic Screen Shake System?

I’ve been trying to achieve a realistic camera shake while walking, sprinting, and holding out items. But it I can seem to figure out how to make it good enough. I played Apeirophobia, and I wanna replicate the same screen shaking effect.
My system:

Their system:

Does anybody know how to actually make a realistic screen shaking system?

10 Likes

My system uses animation when a person begins running depending on the item they are holding out. I also cannot replicate leaning like in their system. And the animations seem pretty laggy.

1 Like

This video will help you if that’s what you’re looking for:

2 Likes

Check out EZ Camera Shake ported to Roblox

1 Like

Here’s an example Camera bobble effect, hope this something you were looking for:

-- << Variables >> --

local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()
local Camera = game:GetService("Workspace").CurrentCamera
local UserInputService = game:GetService("UserInputService")
local Humanoid = Player.Character:WaitForChild("Humanoid")
local bobbing = nil
local func1 = 0
local func2 = 0
local func3 = 0
local func4 = 0
local val = 0
local val2 = 0
local int = 10
local int2 = 10
local vect3 = Vector3.new()

-- << Functions >> --

UserInputService.MouseIconEnabled = false

function lerp(a, b, c)
	return a + (b - a) * c
end

bobbing = game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	deltaTime = deltaTime * 60
	if Humanoid.Health <= 0 then
		bobbing:Disconnect()
		return
	end
	local rootMagnitude = Humanoid.RootPart and Vector3.new(Humanoid.RootPart.Velocity.X, 0, Humanoid.RootPart.Velocity.Z).Magnitude or 0
	local calcRootMagnitude = math.min(rootMagnitude, 50)
	if deltaTime > 3 then
		func1 = 0
		func2 = 0
	else
		func1 = lerp(func1, math.cos(tick() * 0.5 * math.random(10, 15)) * (math.random(5, 20) / 200) * deltaTime, 0.05 * deltaTime)
		func2 = lerp(func2, math.cos(tick() * 0.5 * math.random(5, 10)) * (math.random(2, 10) / 200) * deltaTime, 0.05 * deltaTime)
	end
	Camera.CFrame = Camera.CFrame * (CFrame.fromEulerAnglesXYZ(0, 0, math.rad(func3)) * CFrame.fromEulerAnglesXYZ(math.rad(func4 * deltaTime), math.rad(val * deltaTime), val2) * CFrame.Angles(0, 0, math.rad(func4 * deltaTime * (calcRootMagnitude / 5))) * CFrame.fromEulerAnglesXYZ(math.rad(func1), math.rad(func2), math.rad(func2 * 10)))
	val2 = math.clamp(lerp(val2, -Camera.CFrame:VectorToObjectSpace((Humanoid.RootPart and Humanoid.RootPart.Velocity or Vector3.new()) / math.max(Humanoid.WalkSpeed, 0.01)).X * 0.08, 0.1 * deltaTime), -0.35, 0.2)
	func3 = lerp(func3, math.clamp(UserInputService:GetMouseDelta().X, -5, 5), 0.25 * deltaTime)
	func4 = lerp(func4, math.sin(tick() * int) / 5 * math.min(1, int2 / 10), 0.25 * deltaTime)
	if rootMagnitude > 1 then
		val = lerp(val, math.cos(tick() * 0.5 * math.floor(int)) * (int / 200), 0.25 * deltaTime)
	else
		val = lerp(val, 0, 0.05 * deltaTime)
	end
	if rootMagnitude > 12 then
		int = 20
		int2 = 18
	elseif rootMagnitude > 0.1 then
		int = 12
		int2 = 14
	else
		int2 = 0
	end
	Player.CameraMaxZoomDistance = 0.5
	Player.CameraMinZoomDistance = 0.5
	vect3 = lerp(vect3, Camera.CFrame.LookVector, 0.125 * deltaTime)
end)

Edit: Place this in StarterCharacterScripts as a LocalScript

7 Likes

Not exactly what I need, and I already know how to make your screen and rapidly upon a function.

Can you explain how the lerping function works? I saw it before, but I’m not sure how to use it.

Unfortunately this is not my code, I saw this in a post long time ago but I can’t seem to find it. They also had a good explanation if I can remember right.

I hope the code still helps you what you were looking for :grin:

Alright sounds like a good time to slap on some lofi and study for the next day. Thank you for the help.

1 Like

There’s a very customizable head bobbing script here. It has the bobbing in out effect like in this game, and it’s very easy to make dynamic. Configurable Head Bobbing Script

I hope this was what you’re looking for.

1 Like

Hey I know this is quite an old post but if you’re still looking and want to improve I found their script in the toolbox. I don’t believe it was stolen since the original variables seem to be there and compilers can’t do that. So either it was leaked or released either way it seems very accurate to the game. Here is the script;

local Player = game:GetService("Players").LocalPlayer
local Mouse = Player:GetMouse()
local Camera = game:GetService("Workspace").CurrentCamera
local UserInputService = game:GetService("UserInputService")
local Humanoid = Player.Character:WaitForChild("Humanoid")
local bobbing = nil
local func1 = 0
local func2 = 0
local func3 = 0
local func4 = 0
local val = 0
local val2 = 0
local int = 5
local int2 = 5
local vect3 = Vector3.new()



UserInputService.MouseIconEnabled = false

function lerp(a, b, c)
	return a + (b - a) * c
end

bobbing = game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	deltaTime = deltaTime * 30
	if Humanoid.Health <= 0 then
		bobbing:Disconnect()
		return
	end
	local rootMagnitude = Humanoid.RootPart and Vector3.new(Humanoid.RootPart.Velocity.X, 0, Humanoid.RootPart.Velocity.Z).Magnitude or 0
	local calcRootMagnitude = math.min(rootMagnitude, 25)
	if deltaTime > 1.5 then
		func1 = 0
		func2 = 0
	else
		func1 = lerp(func1, math.cos(tick() * 0.5 * math.random(5, 7.5)) * (math.random(2.5, 10) / 100) * deltaTime, 0.05 * deltaTime)
		func2 = lerp(func2, math.cos(tick() * 0.5 * math.random(2.5, 5)) * (math.random(1, 5) / 100) * deltaTime, 0.05 * deltaTime)
	end
	Camera.CFrame = Camera.CFrame * (CFrame.fromEulerAnglesXYZ(0, 0, math.rad(func3)) * CFrame.fromEulerAnglesXYZ(math.rad(func4 * deltaTime), math.rad(val * deltaTime), val2) * CFrame.Angles(0, 0, math.rad(func4 * deltaTime * (calcRootMagnitude / 5))) * CFrame.fromEulerAnglesXYZ(math.rad(func1), math.rad(func2), math.rad(func2 * 10)))
	val2 = math.clamp(lerp(val2, -Camera.CFrame:VectorToObjectSpace((Humanoid.RootPart and Humanoid.RootPart.Velocity or Vector3.new()) / math.max(Humanoid.WalkSpeed, 0.01)).X * 0.04, 0.1 * deltaTime), -0.12, 0.1)
	func3 = lerp(func3, math.clamp(UserInputService:GetMouseDelta().X, -2.5, 2.5), 0.25 * deltaTime)
	func4 = lerp(func4, math.sin(tick() * int) / 5 * math.min(1, int2 / 10), 0.25 * deltaTime)
	if rootMagnitude > 1 then
		val = lerp(val, math.cos(tick() * 0.5 * math.floor(int)) * (int / 200), 0.25 * deltaTime)
	else
		val = lerp(val, 0, 0.05 * deltaTime)
	end
	if rootMagnitude > 6 then
		int = 10
		int2 = 9
	elseif rootMagnitude > 0.1 then
		int = 6
		int2 = 7
	else
		int2 = 0
	end
	Player.CameraMaxZoomDistance = 0.5
	Player.CameraMinZoomDistance = 0.5
	vect3 = lerp(vect3, Camera.CFrame.LookVector, 0.125 * deltaTime)
end)

I’m gonna be using this to make my own custom character controller its very good and since they use math.random for a lot of the cosine calculations for the camera movement it will be randomized and nothing will ever feel stiff. By far the best camera movement scripts i’ve seen out there.

9 Likes

No offense but this is a bunch of useless numbers. I’ve already gotten a better script.

1 Like

It looks decompiled, as seen in another post about apeirophobia

2 Likes

The best solution in DevForum:

6 Likes

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