Camera acts glitchy and shaky for simple follow script

I’ve set up a simple follow script for a vehicle using :lerp() function. The script is as simple as possible:

Cam.CameraType=Enum.CameraType.Scriptable
local CameraOffsetFromDriveseat = CFrame.new()*CFrame.Angles()
--Basically I just set to however further from camera looks good, keeping it simple

game:GetService("RunService"):BindToRenderStep("CameraFunction",Enum.RenderPriority.Camera.Value+1,function()
	Cam.CFrame=Cam.CFrame:Lerp(CurrentVehicle.DriveSeat.CFrame*CameraOffsetFromDriveseat,0.2)
end)

The script for this couldn’t be simpler, and it should’ve worked perfectly. Instead, this weird shake and glitchy effect occurs, especially when the player’s FPS is low:


I need it to be perfectly smooth whilst having the dynamic effects, especially when drifting.

I have tried many solutions, like putting it on a while true do loop with 0.03 as wait time, so it doesn’t depend on fps, but it doesn’t fix the issue and is not smooth at all.

I have also tried other methods like using TweenService() with ALL the different Enum.EasingStyle and Enum.EasingDirection, but in vain. I have been trying for days and I really needed to resort to seek community help.

Your Lerping the CFrame and its taking 0.2 seconds to reach the target goal. Although, your RenderStepped function is firing 60 times a second.

This means that all your lerps are overlapping eachother. There is probably a much easier way to do this, but for now remove the lerping and just set the Cam cframe to goal cframe.

Let me know if that works!

Setting the Cam.CFrame straight to Goal CFrame would just completely remove the effects, which was the whole point of this script

I really need the effect to remain but the jitter ruins it, I am still stuck on this.

1 Like

Maybe try placing the priority lower than the camera value?

1 Like

I have tried both with the highest priority and lowest, to no solution.

1 Like

Have you tried changing the function to Heartbeat? The car moves in the Heartbeat cycle, while the rendering and your camera runs in the RenderStepped cycle, and those two do not sync together.

1 Like

I have tested with Heartbeat, Stepped and RenderStepped. I have also tested with all RenderPriorities when using RunService:BindToRenderStep() and nothing seems to be the solution, the camera keeps jittering.

From scouring DevForum I’ve actually come to learn why my code is so inefficient, but could still figure no solutions to it. I really need the proper steps I can follow to mitigate this issue.

1 Like

When you said you used TweenService, did you use this:

Cam.CameraType=Enum.CameraType.Scriptable
local CameraOffsetFromDriveseat = CFrame.new()*CFrame.Angles()

local Tween = TweenInfo.new(1)

Vehicle:GetPropertyChangedSignal("CFrame"):Connect(function()
	game:GetService("TweenService"):Create(Cam, Tween, {CFrame = CurrentVehicle.DriveSeat.CFrame*CameraOffsetFromDriveseat}):Play()
end)

:GetPropertyChangedSignal wouldn’t work with physics-related properties, so here’s a modified version:

Cam.CameraType=Enum.CameraType.Scriptable
local CameraOffsetFromDriveseat = CFrame.new()*CFrame.Angles()

local Tween = TweenInfo.new(1)

local OldVehicleCFrame

game:GetService("RunService"):BindToRenderStep("CameraFunction",Enum.RenderPriority.Camera.Value+1,function()
	if OldVehicleCFrame ~= Vehicle.CFrame then return end
	OldVehicleCFrame = Vehicle.CFrame
	game:GetService("TweenService"):Create(Cam, Tween, {CFrame = CurrentVehicle.DriveSeat.CFrame*CameraOffsetFromDriveseat}):Play()
end)
1 Like

I do not understand what this is supposed to change though. The camera is stable at all times except the times when going at high speeds, and this script only focuses on not updating when the car is not moved and does the same when moving as before. So I do not think this will change anything.

1 Like

Huh, that’s weird.

Are you running this on a Localscript or a Serverscript?

1 Like

Ofc a LocalScript, as it is for camera.

1 Like
Cam.CameraType=Enum.CameraType.Scriptable
local CameraOffsetFromDriveseat = CFrame.new()*CFrame.Angles()
--Basically I just set to however further from camera looks good, keeping it simple

local currentTime = 0
game:GetService("RunService"):BindToRenderStep("CameraFunction",Enum.RenderPriority.Camera.Value+1,function(deltaTime)
	currentTime = currentTime + deltaTime * 2
Cam.CFrame=Cam.CFrame:Lerp(CurrentVehicle.DriveSeat.CFrame*CameraOffsetFromDriveseat,currentTime)
end)

I haven’t tested this, and might need to fix it up later. Change the * 2 to change the speed of the camera

I’m sorry but It did not really work probably because in the line currentTime + deltaTime * 2 it just kept adding currentTime with deltaTime*2 each frame and it just kept increasing.

This is what the output said after using print(currentTime):
image

And after some time the currentTime reached really high values:
image

The currentTime is used as Alpha in the lerp() function but it kept increasing in that constant rate beyond it’s limit of 0-1, which probably broke it.

I really need help for it and am really looking forward for a reply. Also, if required, feel free to use this DistanceMoved value which calculates the distance the vehicle moved since last frame, as it may differ time to time:
local DistanceMoved = (CurrentVehicle.DriveSeat.Position-LastPosition).Magnitude

I think I fixed it up, try this. Changing the *2 to a different value should adjust the speed. Set the variable target to the driver seat.

local Cam = workspace.CurrentCamera

local CameraOffsetFromDriveseat = CFrame.new(Vector3.new(0, 15, 15))*CFrame.Angles(0, 0, 0)
--Basically I just set to however further from camera looks good, keeping it simple

local target = workspace:WaitForChild("Part")

game:GetService("RunService"):BindToRenderStep("CameraFunction",Enum.RenderPriority.Camera.Value+1,function(deltaTime)
	Cam.CameraType=Enum.CameraType.Scriptable
	local currentTime = deltaTime*2
	Cam.CFrame = Cam.CFrame:Lerp(CFrame.lookAt(
		(target.CFrame*CameraOffsetFromDriveseat).Position,
		target.Position
	), currentTime)
	Cam.Focus = target.CFrame
end)
2 Likes

Not really worked, as it hugely buffered in presence of lag, especially when explosions go off on screen and the delta between each frame increases, the camera keeps abruptly jumping even when driving in really low speeds.

Whats been working the most so far is:

local LastPosition = CurrentVehicle.DriveSeat.Position
game:GetService("RunService"):BindToRenderStep("CameraFunction",Enum.RenderPriority.Camera.Value+1,function(deltaTime)
	local DistanceMoved = (CurrentVehicle.DriveSeat.Position-LastPosition).Magnitude
	local newalpha = 0.05+(DistanceMoved/7) 
	if newalpha>1 then newalpha=1 end
	Cam.CFrame=Cam.CFrame:Lerp((CurrentVehicle.DriveSeat.CFrame*CameraOffsetFromDriveseat,newalpha)
end

This is the most stable one I’ve tested so far, it completely overlooks the frame and thus it remains stable regardless FPS, even when playing at max graphics at 20 fps it does remain quite stable as it moves according to the DistanceMoved value.

However, we all know this is not the true solution. It does remain stable but it still does consist of mild but noticeable shake effect (not as much as before but still noticable).

I’ve been scouring dev forum and the only thing some people say have 100% worked is something called Critically Damped Springs, but they’re always really vague about it, they don’t provide context upon what it is and how exactly to use it.

There isn’t any tutorial on Youtube about it either. I really need the steps upon what they are and how exactly to use these “Critically Damped Springs” for the simple camera follow script, eliminating the shake.