Assistance required with Custom Camera Bobble

Hello there developers :wave:
I am making a custom camera bobble which rotates the camera on the Z axis (left-to-right), but I am getting an error stating that Error: Argument 3 missing or nil.
Code:

local player = game:GetService("Players").LocalPlayer;
local character = player.Character or player.CharacterAdded:Wait();
local humanoid = character:FindFirstChildWhichIsA("Humanoid");
local hrp = character:WaitForChild("HumanoidRootPart") :: BasePart;

local cc = workspace.CurrentCamera;

local runService = game:GetService("RunService");

local deg = 10;

runService.Heartbeat:Connect(function(dt: number)
	if (humanoid.MoveDirection.Magnitude > 0) then
		local _tick = tick();
		local rotation = CFrame.Angles(0, 0, math.rad(math.sin(_tick) * deg));
		cc.CFrame = cc.CFrame * rotation;
	end;
end);

Please let me know if I am doing something wrong.
Thank you :smiley:

1 Like

I tried your exact code, and got no errors, so I’m not sure why you are having errors.
Also, Z rotation isn’t left to right, Y is.

2 Likes

Strange enough, I’m not getting the error anymore, but I’m also not getting the camera to rotate left and right.


Z rotation isn’t left to right, it’s tilting. Y rotation is left to right.

1 Like

Oh, I’m sorry about that…

But the code still isn’t working D:

Is this what you want? :

local player = game:GetService("Players").LocalPlayer;
local character = player.Character or player.CharacterAdded:Wait();
local humanoid = character:FindFirstChildWhichIsA("Humanoid");
local hrp = character:WaitForChild("HumanoidRootPart") :: BasePart;

local cc = workspace.CurrentCamera;

local runService = game:GetService("RunService");

local wobbleSpeed = 3.125
local strength = 5

runService.Heartbeat:Connect(function(dt: number)
	if (humanoid.MoveDirection.Magnitude > 0) then
		local rotation = CFrame.Angles(0, math.rad(math.sin(tick() * math.pi * wobbleSpeed) * strength * dt), 0);
		cc.CFrame = cc.CFrame * rotation;
	end;
end);
1 Like

:point_down:

:point_down:

I don’t know if you can see the bobble, but it’s there when rotation == CFrame.Angles(0, math.rad(math.sin(tick() * math.pi * wobbleSpeed) * strength * dt), 0);
But not when rotation == CFrame.Angles(0, 0, math.rad(math.sin(tick() * math.pi * wobbleSpeed) * strength * dt));

Yeah, that’s because the default Camera setting doesn’t like to be tilted. Changing the Y rotation works perfectly fine, but trying to change the Z rotation won’t work because of that.

1 Like

How would I make it so that it’d tilt?

You need to set Camera.CameraType = Enum.CameraType.Scriptable and basically make your own camera system.

Alternatively modify the CameraModule script.

1 Like

The problem seems to be that you’re tilting the camera when the Heartbeat event is fired which means that the camera will tilt after the frame is rendered, and in the next frame the default roblox camera script will reset the tilting before it’s rendered
To fix that, you need to use the RenderStepped event, which fires right before the frame is rendered

1 Like

Thank you soooo much denko!
And you too @XSiggeManx for helping me out! :DD

oh sh that works? well do this then haha

local player = game:GetService("Players").LocalPlayer;
local character = player.Character or player.CharacterAdded:Wait();
local humanoid = character:FindFirstChildWhichIsA("Humanoid");
local hrp = character:WaitForChild("HumanoidRootPart") :: BasePart;

local cc = workspace.CurrentCamera;

local runService = game:GetService("RunService");

local wobbleSpeed = 3.125
local strength = 100

runService:BindToRenderStep("CameraTilt", Enum.RenderPriority.Last.Value, function(dt: number)
	if (humanoid.MoveDirection.Magnitude > 0) then
		local rotation = CFrame.Angles(0, 0, math.rad(math.sin(tick() * math.pi * wobbleSpeed) * strength * dt));
		cc.CFrame = cc.CFrame * rotation;
	end;
end);

might wanna reset it when you stop running as well.

1 Like

Actually I just noticed, the game doesn’t really like the tilt being messed with, so it lags back a bunch and doesn’t look too smooth.

While we’re here, can you guys help me figure out how The Mimic Book 2’s movement works?
I was trying to replicate the camera motion from the game…

Yeah I’ve noticed it…
But oh well.

local RunService = game:GetService("RunService")

local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")

local Camera = workspace.CurrentCamera

local function ScaledLerp(a, b, t, dt)
	return a + (b - a) * (1 - math.pow(1 - t, dt * 60))
end

local InterpolationSpeed = 0.25 -- Don't make this greater than 1 or less than 0

local BobbleScaleX = 0.1
local BobbleScaleY = 0.2

local TiltScale = 0.02

local BobbleSpeed = 5

local X = 0
local Y = 0

local TiltZ = 0

RunService.RenderStepped:Connect(function(DeltaTime)
	if Humanoid.MoveDirection.Magnitude > 0 then
		local _tick = tick() * BobbleSpeed
		
		local TargetX = math.sin(_tick) * BobbleScaleX
		local TargetY = (math.abs(math.cos(_tick)) - 1) * BobbleScaleY
		
		local TargetTiltZ = -math.sin(_tick) * TiltScale
		
		X = ScaledLerp(X, TargetX, InterpolationSpeed, DeltaTime)
		Y = ScaledLerp(Y, TargetY, InterpolationSpeed, DeltaTime)
		
		TiltZ = ScaledLerp(TiltZ, TargetTiltZ, InterpolationSpeed, DeltaTime)
	else
		X = ScaledLerp(X, 0, InterpolationSpeed, DeltaTime)
		Y = ScaledLerp(Y, 0, InterpolationSpeed, DeltaTime)
		
		TiltZ = ScaledLerp(TiltZ, 0, InterpolationSpeed, DeltaTime)
	end
	
	Camera.CFrame *= CFrame.fromAxisAngle(Vector3.zAxis, TiltZ) * CFrame.new(X, Y, 0)
end)
2 Likes

OMG THANK YOU SO MUCH DENKO!!!
THANK YOU TOO @XSiggeManx AGAIN!

Hey there, how would I adjust the bobble speed through the player’s walkSpeed?