How to make a camera shake/bob system?

I have no clue how to make something like this that works in 3rd person. Does anyone here know how?

I can only find resources for first person and the ones for third person don’t really work that great

1 Like

You didn’t look hard enough :slight_smile:

1 Like

That’s not what I’m looking for. I have used that module several times. I want bobbing / shaking when walking and that module just wouldn’t work

1 Like

try searching around the toolbox, theres a ton of scripts for this and they work by modifying the CurrentCamera

--CBob script with a tilt. org.by:IAmDevForumMember
task.wait(3) --StarterCharacterScripts.LocalScript
local Workspace = game:GetService("Workspace")
local RunService = game:GetService("RunService")
local LocalPlayer = game:GetService("Players").LocalPlayer
local UserInputService = game:GetService("UserInputService")
local Root = LocalPlayer.Character:WaitForChild("HumanoidRootPart")
local Mouse, Camera  = LocalPlayer:GetMouse(), Workspace.CurrentCamera
local angleX, x, y, tilt, vX, vY, sX, sY = 0, 0, 0, 0, 0, 0, 10, 10
local TouchEnabled = UserInputService.TouchEnabled
--* UserInputService.MouseIconEnabled = flase
local randomX, randomY = nil, nil
local function lerp(v1, v2, t)
	return v1 + (v2 - v1) * t
end --rewrite.by:2112Jay

RunService.RenderStepped:Connect(function(dt)
	local velocity = Root.Velocity.magnitude
	if velocity > 0.02 then dt *= 60 randomX = math.random(1, 2) randomY = math.random(1, 2) --x(10,15), y(5,10)
		vX = dt <= 2 and lerp(vX, math.cos(tick() * 0.5 * randomX) * (math.random(5, 20) / 200) * dt, 0.05 * dt) or 0
		vY = dt <= 2 and lerp(vY, math.cos(tick() * 0.5 * randomY) * (math.random(2, 10) / 200) * dt, 0.05 * dt) or 0
		
		Camera.CFrame *= CFrame.Angles(0, 0, math.rad(angleX))
			* CFrame.Angles(math.rad(math.clamp(x * dt, -0.15, 0.15)), math.rad(math.clamp(y * dt, -0.5, 0.5)), tilt)
			* CFrame.Angles(math.rad(vX), math.rad(vY), math.rad(vY * 10))
		
		tilt = math.clamp(lerp(tilt, -Camera.CFrame:VectorToObjectSpace((Root and Root.Velocity or 
			Vector3.new()) / math.max(LocalPlayer.Character.Humanoid.WalkSpeed, 0.01)).X * 0.05, 0.1 * dt), -0.05, 0.05)
		
		if not TouchEnabled and dt < 2 then
			angleX = lerp(angleX, math.clamp(UserInputService:GetMouseDelta().X / dt * 0.15, -2.5, 2.5), 0.25 * dt)
		end x = lerp(x, math.sin(tick() * sX) / 5 * math.min(1, sY / 10), 0.25 * dt)
		y = velocity > 1 and lerp(y, math.cos(tick() * 0.5 * math.floor(sX)) * (sX / 200), 0.25 * dt) or lerp(y, 0, 0.05 * dt)
		sX, sY = velocity > 12 and 20 or (velocity > 0.1 and 12 or 0), velocity > 0.1 and 18 or (velocity > 0.1 and 14 or 0)
	end
end)

Also repacked that shaker for easy set up and use …
CameraShaker.rbxm (8.0 KB)

This script posted has a bunch of settings that can be tweaked. You’ll have to mess around with it to find your sweet spot.

2 Likes

If you want to learn the basics of a camera shake / bobble system. I would highly recommend taking a look at Okeanskiys video on a basic camera shake system.

2 Likes

I have a formula for such bob. Here it is:

local bobbleX = math.cos(tick() * desiredVelocity / 2) * math.sqrt(velocity / 16) * (InAir() and 0.5 or 2)
local bobbleY = math.abs(math.sin(tick() * desiredVelocity / 2)) * math.sqrt(velocity / 16) * (InAir() and 0.5 or 2)

local noiseX = math.noise(tick()/10,os.clock()/10)*5
local noiseY = math.noise(os.clock()/10,tick()/10)*5 + math.sin(tick()*2)/2

It has some random movement as well indicated by the noise and it does increase/decrease depending on the player’s speed.

Here is what the 2 variables, desiredVelocity and velocity mean:

  • desiredVelocity: It’s the players velocity but rounded, so you need to use math.round.
  • velocity: The player’s current velocity.

You could remove the noise as well if you want.

I would say to put them in this way:

local verticalRotation = bobbleY + noiseY
local horizontalRotation = bobbleX + noiseX
local tiltedRotation = bobbleX

You could also make it shake a bit if you increase the noiseX and noiseY.

3 Likes

This solution also worked very well for me, thanks. I made the other one the solution primarily because it was posted first, I’ll conduct further testing to see which one I like better. Thanks.

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