Hello. The script below works as intended; it makes the camera of the player have some “delay” when the player moves or rotates their camera. But as you can see with the video below the script the problem is that it’s choppy. How can I fix this? Thank you in advance
LocalScript in StarterCharacterScripts
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Directories
local Modules = ReplicatedStorage:WaitForChild("Modules")
local PhysicsModules = Modules:WaitForChild("Physics")
-- Modules
local DefaultioSpring = require(PhysicsModules:WaitForChild("DefaultioSpring"))
-- Variables
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Camera = workspace.CurrentCamera
-- Smooth Camera Variables
local Spring = DefaultioSpring.new(Vector3.new())
Spring.Damper = 2
Spring.Speed = 50
RunService.RenderStepped:Connect(function(dt)
local Rotation = CFrame.new(Camera.CFrame:ToEulerAnglesXYZ())
local CameraRotation = CFrame.Angles(Rotation.X, Rotation.Y, Rotation.Z)
Spring.Target = Camera.CFrame.Position
Camera.CFrame = CFrame.new(Spring.Position) * CameraRotation
end)
Defaultio’s spring module (What I used):
--[[
class Spring
Description:
A physical model of a spring, useful in many applications. Properties only evaluate
upon index making this model good for lazy applications
API:
Spring = Spring.new(number position)
Creates a new spring in 1D
Spring = Spring.new(Vector3 position)
Creates a new spring in 3D
Spring.Position
Returns the current position
Spring.Velocity
Returns the current velocity
Spring.Target
Returns the target
Spring.Damper
Returns the damper
Spring.Speed
Returns the speed
Spring.Target = number/Vector3
Sets the target
Spring.Position = number/Vector3
Sets the position
Spring.Velocity = number/Vector3
Sets the velocity
Spring.Damper = number [0, 1]
Sets the spring damper, defaults to 1
Spring.Speed = number [0, infinity)
Sets the spring speed, defaults to 1
Spring:TimeSkip(number DeltaTime)
Instantly skips the spring forwards by that amount of now
Spring:Impulse(number/Vector3 velocity)
Impulses the spring, increasing velocity by the amount given
Visualization (by Defaultio):
https://www.desmos.com/calculator/hn2i9shxbz
]]
local Spring = {}
--- Creates a new spring
-- @param initial A number or Vector3 (anything with * number and addition/subtraction defined)
-- @param[opt=os.clock] clock function to use to update spring
function Spring.new(initial, clock)
local target = initial or 0
clock = clock or os.clock
return setmetatable({
_clock = clock;
_time0 = clock();
_position0 = target;
_velocity0 = 0*target;
_target = target;
_damper = 1;
_speed = 1;
}, Spring)
end
--- Impulse the spring with a change in velocity
-- @param velocity The velocity to impulse with
function Spring:Impulse(velocity)
self.Velocity = self.Velocity + velocity
end
--- Skip forwards in now
-- @param delta now to skip forwards
function Spring:TimeSkip(delta)
local now = self._clock()
local position, velocity = self:_positionVelocity(now+delta)
self._position0 = position
self._velocity0 = velocity
self._time0 = now
end
function Spring:__index(index)
if Spring[index] then
return Spring[index]
elseif index == "Value" or index == "Position" or index == "p" then
local position, _ = self:_positionVelocity(self._clock())
return position
elseif index == "Velocity" or index == "v" then
local _, velocity = self:_positionVelocity(self._clock())
return velocity
elseif index == "Target" or index == "t" then
return self._target
elseif index == "Damper" or index == "d" then
return self._damper
elseif index == "Speed" or index == "s" then
return self._speed
elseif index == "Clock" then
return self._clock
else
error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
end
end
function Spring:__newindex(index, value)
local now = self._clock()
if index == "Value" or index == "Position" or index == "p" then
local _, velocity = self:_positionVelocity(now)
self._position0 = value
self._velocity0 = velocity
self._time0 = now
elseif index == "Velocity" or index == "v" then
local position, _ = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = value
self._time0 = now
elseif index == "Target" or index == "t" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._target = value
self._time0 = now
elseif index == "Damper" or index == "d" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._damper = value
self._time0 = now
elseif index == "Speed" or index == "s" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._speed = value < 0 and 0 or value
self._time0 = now
elseif index == "Clock" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._clock = value
self._time0 = value()
else
error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
end
end
function Spring:_positionVelocity(now)
local p0 = self._position0
local v0 = self._velocity0
local p1 = self._target
local d = self._damper
local s = self._speed
local t = s*(now - self._time0)
local d2 = d*d
local h, si, co
if d2 < 1 then
h = math.sqrt(1 - d2)
local ep = math.exp(-d*t)/h
co, si = ep*math.cos(h*t), ep*math.sin(h*t)
elseif d2 == 1 then
h = 1
local ep = math.exp(-d*t)/h
co, si = ep, ep*t
else
h = math.sqrt(d2 - 1)
local u = math.exp((-d + h)*t)/(2*h)
local v = math.exp((-d - h)*t)/(2*h)
co, si = u + v, u - v
end
local a0 = h*co + d*si
local a1 = 1 - (h*co + d*si)
local a2 = si/s
local b0 = -s*si
local b1 = s*si
local b2 = h*co - d*si
return a0*p0 + a1*p1 + a2*v0, b0*p0 + b1*p1 + b2*v0
end
return Spring
Again, thank you in advance