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.
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.
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.
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)
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.
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):
And after some time the currentTime reached really high values:
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)
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.