I’m using a Spring Module to create a realistic camera bob when the player jumps. For some reason, the camera jitters whenever the spring has velocity added to it. Here’s the code,
--!strict
-- Services
local UserInputService = game:GetService('UserInputService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local RunService = game:GetService('RunService')
local Players = game:GetService('Players')
-- Types
type BobberImp = {
__index: BobberImp,
new: (Camera: Camera) -> Bobber,
StartBobber: (Bobber) -> (),
Jump: (Bobber) -> (),
Destroy: (Bobber) -> (),
}
type Bobber = {
Camera: Camera,
BobTick: number,
Connection: RBXScriptConnection?,
StartBobber: (Bobber: Bobber) -> (),
Jump: (Bobber) -> (),
Destroy: (Bobber: Bobber) -> (),
SpringX: Spring.SpringObject,
SpringY: Spring.SpringObject,
SpringZ: Spring.SpringObject,
LastStep: number,
OldCamCF: CFrame,
Character: Model?,
Humanoid: Humanoid,
}
-- Constants
local Player = Players.LocalPlayer :: Player
local Common = ReplicatedStorage.Common
local Spring = require(Common.Spring)
-- Main
local CameraBobber = {} :: BobberImp
CameraBobber.__index = CameraBobber
function CameraBobber.new(camera: Camera) : Bobber
local self = setmetatable({}, CameraBobber) :: Bobber
self.Camera = camera
self.Character = Player.Character
self.Humanoid = self.Character.Humanoid :: Humanoid
self.Connection = nil
self.LastStep = tick()
self.OldCamCF = camera.CFrame
self.SpringX = Spring.new(3, 2, 16, 0, 0, 1) :: Spring.SpringObject
self.SpringY = Spring.new(3, 2, 16, 0, 0, 1) :: Spring.SpringObject
self.SpringZ = Spring.new(3, 2, 16, 0, 0, 1) :: Spring.SpringObject
self:StartBobber()
return self
end
function CameraBobber.Jump(self: Bobber)
self.SpringX:AddVelocity(-12)
self.SpringZ:AddVelocity(75)
end
function CameraBobber.StartBobber(self: Bobber)
UserInputService.JumpRequest:Connect(function()
self:Jump()
end)
self.Connection = RunService.RenderStepped:Connect(function(deltaTime: number)
if self.Humanoid.MoveDirection.Magnitude > 0 then
if tick() - self.LastStep >= 1 then
self.LastStep = tick()
end
end
local offsetX = math.rad(self.SpringX.Offset)
local offsetY = math.rad(self.SpringY.Offset)
local offsetZ = math.rad(self.SpringZ.Offset)
local newCamCF = CFrame.Angles(offsetX, offsetY, offsetZ)
local goalCF = newCamCF:ToObjectSpace(self.OldCamCF)
self.Camera.CFrame *= goalCF
self.OldCamCF = newCamCF
end)
end
function CameraBobber.Destroy(self: Bobber)
if self.Connection then
self.Connection:Disconnect()
self.Connection = nil
end
end
return CameraBobber
If you have anything to share, please do. Thanks for reading!