I am currently making a isometric camera for a game, and I realized that my camera has slightly jittery movements when I move my character around: (Hard to notice in the video, but it is there!)
Here is the relevant code:
self._updateCamera = function(deltaTime: number)
if self._originPart then
local originPosition: Vector3 = self._originPart.Position + Vector3.new(0, self._height.Value, 0)
local approximateFPS: number = 1 / deltaTime
local fpsRatio: number = LERP_ALPHA * (60 / approximateFPS)
local cameraPosition: Vector3? = if originPosition
then originPosition + Vector3.new(self._xDepth.Value, self._yDepth.Value, self._zDepth.Value)
else warn("[IsometricCamera] Camera point does not exist!")
if cameraPosition then
camera.CFrame =
camera.CFrame:Lerp(CFrame.lookAt(cameraPosition, originPosition), math.clamp(fpsRatio, 0, 1))
end
end
end
-- Setting the camera
camera.CameraType = Enum.CameraType.Scriptable
camera.FieldOfView = DEFAULT_FOV
RunService:BindToRenderStep(BIND_RENDER_NAME, Enum.RenderPriority.Camera.Value + 1, self._updateCamera)
I’ve tried using RenderStepped, but seemed to replicate the same results. I reckon that it has to do something with a delay in the rendering resulting in the previous frame being calculated. Again, I am not too sure and would appreciate help and any code examples
Unfortunately, Heartbeat shouldn’t work because it only runs after the frame is rendered. (Which is why I went with RenderStepped and BindToRenderStepped)
I have also tested it, and the jittery results remain.
local function lerp(a, b, t)
return a + ( b - a ) * t
end
So now, the code should look like this.
local function lerp(a, b, t)
return a + (b - a) * t
end
self._updateCamera = function(deltaTime: number)
if self._originPart then
local originPosition: Vector3 = self._originPart.Position + Vector3.new(0, self._height.Value, 0)
local approximateFPS: number = 1 / deltaTime
local fpsRatio: number = LERP_ALPHA * (60 / approximateFPS)
local cameraPosition: Vector3? = if originPosition
then originPosition + Vector3.new(self._xDepth.Value, self._yDepth.Value, self._zDepth.Value)
else warn("[IsometricCamera] Camera point does not exist!")
if cameraPosition then
local camCFrame = lerp(camera.CFrame, CFrame.lookAt(cameraPosition, originPosition, math.clamp(fpsRatio, 0, 1))
camera.CFrame = camCFrame
end
end
end
-- Setting the camera
camera.CameraType = Enum.CameraType.Scriptable
camera.FieldOfView = DEFAULT_FOV
RunService:BindToRenderStep(BIND_RENDER_NAME, Enum.RenderPriority.Camera.Value + 1, self._updateCamera)
Getting and using the Stepped and RenderStepped deltas.
Using many different RenderPriorities (including before camera).
Getting the delta from a separate thread.
Using a custom lerp function (although I am almost certain the issue lies with RunService).
I am lerping the position of a part and incorporating the delta in the speed calculation.
I have also ruled out the issue been the camera and determined it’s an issue with the part movement.
The problem is that every 5-6 seconds there will be a period of micro stuttering. I assume it has something to do with tasks been scheduled at that point in the frame?
I am going to have to do some exploring with the MicroProfiler but I don’t think there is much I can do to solve it.
Any support or ideas would be much appreciated.
Thanks