Hello scripters (particularly camera manipulators), what would be your preferred solution for stuttering or choppy custom cameras? I’m quite a “beginner” in this field, so I may need some help.
Currently, it doesn’t stutter as it’s not lerping the CurrentCamera CFrame; however, when I tried to lerp it with a small number as its alpha, it started becoming choppy when moving from side to side.
What I want to achieve: Smooth camera lerping without stutter, particularly in implementing camera delay or bobble.
RunService:BindToRenderStep("cameraMovement "..self.Settings.weaponName, Enum.RenderPriority.Camera.Value + 1, function(dT)
-- OTS camera system.
local startCFrame = CFrame.new(Character.HumanoidRootPart.Position) * CFrame.Angles(0, math.rad(self.Settings.cameraAngles.AngleX), 0) * CFrame.Angles(math.rad(self.Settings.cameraAngles.AngleY), 0, 0)
local cameraCFrame = startCFrame:PointToWorldSpace(self.Settings.cameraOffset)
local cameraFocus = startCFrame:PointToWorldSpace(Vector3.new(self.Settings.cameraOffset.X, self.Settings.cameraOffset.Y, -10000))
local resultingCameraCFrame : CFrame = CFrame.new(cameraCFrame, cameraFocus)
-- Setup camera movement.
if self.Settings.cameraAlpha.Value >= 1 then
CurrentCamera.CFrame = resultingCameraCFrame
elseif self.Settings.cameraAlpha.Value < 1 then
local distance = (cameraCFrame - startCFrame.Position).Magnitude
self.Settings.cameraAlpha.Value += dT / (distance / 20)
CurrentCamera.CFrame = CurrentCamera.CFrame:Lerp(resultingCameraCFrame, self.Settings.cameraAlpha.Value)
end
local RootPart = Character.HumanoidRootPart
local lookingCFrame = CurrentCamera.CFrame:PointToWorldSpace(Vector3.new(0, 0, -10000))
local rootLookDirection = (lookingCFrame - RootPart.CFrame.Position)
local rootYaw = math.atan2(-rootLookDirection.X, -rootLookDirection.Z)
RootPart.CFrame = CFrame.new(RootPart.CFrame.Position) * CFrame.Angles(0, rootYaw, 0) -- I was testing some trigonometry here. C:
if not self.Settings.isFirearmEquipped and not self.Settings.hasWeaponEquipped.Value then
CurrentCamera.CameraType = Enum.CameraType.Custom
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
self.Settings.cameraAlpha.Value = 0
RunService:UnbindFromRenderStep("cameraMovement "..self.Settings.weaponName)
elseif not self.Settings.isFirearmEquipped and self.Settings.hasWeaponEquipped.Value then
RunService:UnbindFromRenderStep("cameraMovement "..self.Settings.weaponName)
end
end)
(I know, my code structure’s lowk meh, but I just need a solution for lerping camera without stutter before moving to fixing that)
Oh, I forgot to fix that. Thanks for bringing that up.
But here’s the video when I implement this code block:
RunService:BindToRenderStep("cameraMovement "..self.Settings.weaponName, Enum.RenderPriority.Camera.Value + 1, function(dT)
-- OTS camera system.
local startCFrame = CFrame.new(Character.HumanoidRootPart.Position) * CFrame.Angles(0, math.rad(self.Settings.cameraAngles.AngleX), 0) * CFrame.Angles(math.rad(self.Settings.cameraAngles.AngleY), 0, 0)
local cameraCFrame = startCFrame:PointToWorldSpace(self.Settings.cameraOffset)
local cameraFocus = startCFrame:PointToWorldSpace(Vector3.new(self.Settings.cameraOffset.X, self.Settings.cameraOffset.Y, -10000))
local resultingCameraCFrame : CFrame = CFrame.new(cameraCFrame, cameraFocus)
-- Setup camera movement.
if self.Settings.cameraAlpha.Value >= 1 then
-- OTS state.
CurrentCamera.CFrame = CurrentCamera.CFrame:Lerp(resultingCameraCFrame, 0.1)
-- As you can see, I tried lerping it to 0.1, but it ended up stuttering the character when I move sideways.
elseif self.Settings.cameraAlpha.Value < 1 then
-- Transition the camera to OTS.
local distance = (cameraCFrame - startCFrame.Position).Magnitude
self.Settings.cameraAlpha.Value += math.clamp(dT / (distance / 20), 0, 1)
CurrentCamera.CFrame = CurrentCamera.CFrame:Lerp(resultingCameraCFrame, self.Settings.cameraAlpha.Value)
end
local RootPart = Character.HumanoidRootPart
local lookingCFrame = CurrentCamera.CFrame:PointToWorldSpace(Vector3.new(0, 0, -10000))
local rootLookDirection = (lookingCFrame - RootPart.CFrame.Position)
local rootYaw = math.atan2(-rootLookDirection.X, -rootLookDirection.Z)
RootPart.CFrame = CFrame.new(RootPart.CFrame.Position) * CFrame.Angles(0, rootYaw, 0) -- I was testing some trigonometry here. C:
if not self.Settings.isFirearmEquipped and not self.Settings.hasWeaponEquipped.Value then
CurrentCamera.CameraType = Enum.CameraType.Custom
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
self.Settings.cameraAlpha.Value = 0
RunService:UnbindFromRenderStep("cameraMovement "..self.Settings.weaponName)
elseif not self.Settings.isFirearmEquipped and self.Settings.hasWeaponEquipped.Value then
RunService:UnbindFromRenderStep("cameraMovement "..self.Settings.weaponName)
end
end)
I haven’t implemented CFrame lerping during the OTS state. Though when I lerp it in its OTS state, the character started to stutter on my screen, which is the issue.
Is there a way to lessen the stutter (or remove it completely)?
Maybe focus on this code block now:
-- Setup camera movement.
if self.Settings.cameraAlpha.Value >= 1 then
-- OTS state.
CurrentCamera.CFrame = CurrentCamera.CFrame:Lerp(resultingCameraCFrame, 0.1)
-- As you can see, I tried lerping it to 0.1, but it ended up stuttering the character when I move sideways.
elseif self.Settings.cameraAlpha.Value < 1 then
-- Transition the camera to OTS.
local distance = (cameraCFrame - startCFrame.Position).Magnitude
self.Settings.cameraAlpha.Value += math.clamp(dT / (distance / 20), 0, 1)
CurrentCamera.CFrame = CurrentCamera.CFrame:Lerp(resultingCameraCFrame, self.Settings.cameraAlpha.Value)
end
If you’re talking about the choppiness on the character when moving, you can try to set the humanoid’s AutoRotate property to false when using the custom lock on. Otherwise, try using an AlignOrientation instance instead of changing the rootpart‘s cframe
Anyways, I found a solution to make it smoother.
I utilized an Exponential equation for the alpha; based on more in-depth research, this is the closest I can get to achieving a smooth camera lerp without using a Spring module.
I don’t know, maybe it’s smoother for you guys now if you try this one out:
function createLerp:Exponential(deltaTime, speed)
return 1 - 0.01 ^ (deltaTime * speed)
-- Recommended speed: 1-5, exceeding this limit caused it to jitter for me.
end