I have a script that rotates the camera left and right based on the humanoid’s MoveDirection, and it works perfectly as I want it to, but only side-to-side:

…but trying to add functionality to make it tilt the same way front and back doesn’t work nearly as well.

It moves way too much, and doesn’t go back into place, like it’s constantly being added onto, unlike the other axis. I’ve tried a few things, like basing it off of MoveVector instead of MoveDirection, but I wasn’t able to get it working like how I wanted, and don’t fully understand how it snaps back into place. Here is the code:
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Camera = workspace.CurrentCamera
local Character = Player.Character or Player.CharacterAdded:Wait()
local HRP = Character:WaitForChild("HumanoidRootPart")
Camera.CameraSubject = HRP
Camera.CameraType = Enum.CameraType.Follow
Camera.FieldOfView = 80
local rad = math.rad
local Rot = CFrame.new()
local function GetRollRightAngle()
local Character = Player.Character
if not Character then
return
end
local Cf = Camera.CFrame
return -Cf.RightVector:Dot(Character.Humanoid.MoveDirection)
end
local function GetRollLookAngle()
local Character = Player.Character
if not Character then
return
end
local Cf = Camera.CFrame
return -Cf.UpVector:Dot(Character.Humanoid.MoveDirection)
end
RunService:BindToRenderStep("RotateCameraInPlayerDir", Enum.RenderPriority.Camera.Value + 1, function()
local RollRight = GetRollRightAngle() * -12
local RollLook = GetRollLookAngle() * -10
Rot = Rot:Lerp(CFrame.Angles(rad(RollLook), 0, rad(RollRight)), 0.2)
Camera.CFrame *= Rot
end)