I’ve been having a lot of trouble with smoothing my camera for a bit now. I’ve managed to get the overall smoothing right but I have two outstanding problems right now:
- It tends to jitter when rotated on the X axis
- When the camera’s rotation is negative, it returns to 0 instead of smoothly transitioning
Here are is an example:
and the code responsible for my camera:
local player = game.Players.LocalPlayer
local RunService = game:GetService("RunService")
local camera = game.Workspace.Camera
local mouse = player:GetMouse()
local userInputService = game:GetService("UserInputService")
local ts = game:GetService("TweenService")
local ti = TweenInfo.new(0.3)
local smoothDamp = require(game.ReplicatedStorage.SmoothDampAlgorithm)
local smoothX = smoothDamp.new()
local smoothY = smoothDamp.new()
local mouseX
local mouseY
local xRotation = 0
local yRotation = 0
local dampenedMouseX = 0
local dampenedMouseY = 0
local Sensitivity = 20
local character
local canMoveCam = true
local MouseDeltaMagnitude
player.CharacterAppearanceLoaded:Connect(function(char)
canMoveCam = true
character = char
character.Humanoid.AutoRotate = false
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
for i, v in pairs(char:GetChildren()) do
if v:IsA("BasePart") and v.Name ~= "Head" then
v.LocalTransparencyModifier = v.Transparency
v:GetPropertyChangedSignal("LocalTransparencyModifier"):Connect(function()
v.LocalTransparencyModifier = v.Transparency
end)
end
end
for _, v in pairs(char:GetChildren()) do
if v:IsA("Accessory") then
v:WaitForChild("Handle").Transparency = 1
end
end
local cameraUpdate = RunService.RenderStepped:Connect(function(deltaTime)
local mousePos = userInputService:GetMouseDelta()
mouseX = mousePos.X * deltaTime * Sensitivity
mouseY = mousePos.Y * deltaTime * Sensitivity
MouseDeltaMagnitude = userInputService:GetMouseDelta().X
xRotation -= mouseY
xRotation = math.clamp(xRotation, -20, 60)
local xRotDead = math.clamp(xRotation, -45, 45)
yRotation = yRotation + mouseX
mouseX = math.clamp(mouseX, mouseX -.2, mouseX + .2)
dampenedMouseX = math.deg(smoothX:SmoothDampAngleF(camera.CFrame.Rotation.X, math.rad(xRotation), .4, deltaTime))
dampenedMouseY = smoothY:SmoothDampAngleF(character.HumanoidRootPart.CFrame.Rotation.Y, mouseX, .4, deltaTime )
camera.CFrame = CFrame.new(character.Head.CFrame.Position)
if canMoveCam then
-- Line of interest
camera.CFrame = (camera.CFrame * ((character.HumanoidRootPart.CFrame.Rotation ) * CFrame.Angles(dampenedMouseX,0, 0)))
character.HumanoidRootPart.CFrame = (character.HumanoidRootPart.CFrame * CFrame.Angles(0, -dampenedMouseY, 0))
else
camera.CFrame = (camera.CFrame * ( character.Head.CFrame.Rotation * CFrame.Angles( math.rad(xRotDead), math.rad(yRotation), 0)))
end
end)
character.Humanoid.Died:Connect(function()
canMoveCam = false
task.wait(15)
cameraUpdate:Disconnect()
end)
end)
mouse.Button1Down:Connect(function()
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
userInputService.MouseIconEnabled = false
end)
mouse.Button2Down:Connect(function()
userInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
userInputService.MouseIconEnabled = false
end)
and the smoothdamp module (Updated version of @sleitnick’s module which can be found here):
local SmoothDamp = {}
SmoothDamp.__index = SmoothDamp
function SmoothDamp.new()
return setmetatable({
MaxSpeed = math.huge;
_update = time();
_velocity = 1;
}, SmoothDamp)
end
local function DeltaAngle(current, target)
local delta = (target-current) % math.rad(360)
if delta > math.rad(180) then
delta -= math.rad(360)
end
return delta
end
function SmoothDamp:SmoothDampF(current, target, smoothTime, deltaTime)
local currentVelocity = self._velocity
local now = time()
-- local deltaTime = (now - self._update)
smoothTime = math.max(0.0001, smoothTime)
local num = (2 / smoothTime)
local num2 = (num * deltaTime)
local d = (1 / (1 + num2 + 0.48 * num2 * num2 + 0.235 * num2 * num2 * num2))
local change = (current - target)
local originalTo = target
local maxLength = (self.MaxSpeed * smoothTime)
change = math.clamp(change, -maxLength, maxLength)
target = (current - change)
local temp = ((currentVelocity + num * change) * deltaTime)
currentVelocity = ((currentVelocity - num * temp) * d)
local output = (target + (change + temp) * d)
if ((originalTo - current) > 0) == (output > originalTo) then
output = originalTo
currentVelocity = (output - originalTo) / deltaTime
end
self._velocity = currentVelocity
self._update = now
return output
end
function SmoothDamp:SmoothDampAngleF(current, target, smoothTime, deltaTime)
target = current + DeltaAngle(current, target)
return self:SmoothDampF(current, target, smoothTime, deltaTime)
end
return SmoothDamp
I’ve been stuck on this for so long now and any help would be massively appreciated!