Hello there developers
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
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);
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.
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
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.
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)