Issue with lerp smoothing and FPS

This issue started when I started to test the jeeps, it first started flinging.However, I Put the right modification into the jeep to make it not fling by reducing the suspension value. As of now I have a big problem the speeds are fps dependent which means it just decreases on low fps and increases on high fps. I’ve tried multiple methods like Lerp smoothing, but it did not go at the same speed and pace as normal at 60 fps. How do I fix this?

here’s the code

	while character.Humanoid.SeatPart == car.DriveSeat do
		game:GetService("RunService").RenderStepped:wait()

		--Broken gyro input
		--[[if userInputService.GyroscopeEnabled then
			local inputObject, cframe = userInputService:GetDeviceRotation()
			local up = cframe:vectorToWorldSpace(Vector3.new(0, 1, 0))
			local angle = (1 - up.Y) * (math.abs(up.X) / up.X)
			movement = Vector2.new(angle, movement.Y)
		end]]

		if IsGrounded() then
			if movement.Y ~= 0 then
				local velocity = car.Chassis.CFrame.lookVector * movement.Y * stats.Speed.Value
				car.Chassis.Velocity = car.Chassis.Velocity:Lerp(velocity, 0.1)
				bodyVelocity.maxForce = Vector3.zero
			else
				bodyVelocity.maxForce = Vector3.new(mass / 1.1, mass / (2*x), mass / 1.1 )
			end
			local rotVelocity = car.Chassis.CFrame:vectorToWorldSpace(Vector3.new(movement.Y * stats.Speed.Value / 50, 0, -car.Chassis.RotVelocity.Y * 5 * movement.Y))
			local speed = -car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity).unit.Z
			rotation = rotation + math.rad((-stats.Speed.Value / 5) * movement.Y)
			if math.abs(speed) > 0.1 then
				rotVelocity = rotVelocity + car.Chassis.CFrame:vectorToWorldSpace((Vector3.new(0, -movement.X * speed * stats.TurnSpeed.Value, 0)))
				bodyAngularVelocity.maxTorque = Vector3.zero
			else
				bodyAngularVelocity.maxTorque = Vector3.new(mass / x, mass/ 1.1 * x , mass/ 1.1)
			end
			car.Chassis.RotVelocity = car.Chassis.RotVelocity:Lerp(rotVelocity, 0.1)

			--bodyVelocity.maxForce = Vector3.new(mass / 3, mass / 6, mass / 3)
			--bodyAngularVelocity.maxTorque = Vector3.new(mass / 6, mass / 3, mass / 6)
		else
			bodyVelocity.maxForce = Vector3.zero
			bodyAngularVelocity.maxTorque = Vector3.zero
		end

		for i, part in pairs(car:GetChildren()) do
			if part.Name == "Thruster" then
				UpdateThruster(part)
			end
		end
	end
	for i, v in pairs(car:GetChildren()) do
		if v:FindFirstChild("BodyThrust") then
			v.BodyThrust:Destroy()
		end
	end
	bodyVelocity:Destroy()
	bodyAngularVelocity:Destroy()
	camera.CameraType = oldCameraType
	userInputService.ModalEnabled = false
	script:Destroy()
end)

Change game:GetService("RunService").RenderStepped:wait() to local dt = game:GetService("RunService").RenderStepped:Wait()
Then in any section where you add to the velocity, multiply the velocity addition by (dt * 60), assuming you were testing on 60 FPS

so like lerp(rotvelocity * (dt*60),0.1)

No, in the addition, like if you had
velocity = velocity + speed
you’d do
velocity = velocity + (speed * dt * 60)

I only see that in rot velocity

end
local rotVelocity = car.Chassis.CFrame:vectorToWorldSpace(Vector3.new(movement.Y * stats.Speed.Value / 50, 0, -car.Chassis.RotVelocity.Y * 5 * movement.Y)) * (60*dt)
local speed = -car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity).unit.Z * (60 * dt)

Yeah you could try that, but it mostly only fits if you’re adding a Vector3 to your main velocity

actually do it for me I want to see what you mean?

local speed = -car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity).unit.Z
local speed = -car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity).unit.Z * (dt * 60)

But, are you using Lerp(x, 0.1) for friction?

x is for friction. I could send other values if you want

this did not work can u implement what you mean to the whole script please

	while character.Humanoid.SeatPart == car.DriveSeat do
		game:GetService("RunService").RenderStepped:wait()

		--Broken gyro input
		--[[if userInputService.GyroscopeEnabled then
			local inputObject, cframe = userInputService:GetDeviceRotation()
			local up = cframe:vectorToWorldSpace(Vector3.new(0, 1, 0))
			local angle = (1 - up.Y) * (math.abs(up.X) / up.X)
			movement = Vector2.new(angle, movement.Y)
		end]]

		if IsGrounded() then
			if movement.Y ~= 0 then
				local velocity = car.Chassis.CFrame.lookVector * movement.Y * stats.Speed.Value * dt * 60
				car.Chassis.Velocity = car.Chassis.Velocity:Lerp(velocity, 0.1)
				bodyVelocity.maxForce = Vector3.zero
			else
				bodyVelocity.maxForce = Vector3.new(mass / 1.1, mass / (2*x), mass / 1.1 )
			end
			local rotVelocity = car.Chassis.CFrame:vectorToWorldSpace(Vector3.new(movement.Y * stats.Speed.Value / 50, 0, -car.Chassis.RotVelocity.Y * 5 * movement.Y) * dt * 60)
			local speed = -car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity).unit.Z * dt * 60
			rotation = rotation + math.rad((-stats.Speed.Value / 5) * movement.Y) * dt * 60
			if math.abs(speed) > 0.1 then
				rotVelocity = rotVelocity + car.Chassis.CFrame:vectorToWorldSpace((Vector3.new(0, -movement.X * speed * stats.TurnSpeed.Value, 0)))
				bodyAngularVelocity.maxTorque = Vector3.zero
			else
				bodyAngularVelocity.maxTorque = Vector3.new(mass / x, mass/ 1.1 * x , mass/ 1.1)
			end
			car.Chassis.RotVelocity = car.Chassis.RotVelocity:Lerp(rotVelocity, 0.1)

			--bodyVelocity.maxForce = Vector3.new(mass / 3, mass / 6, mass / 3)
			--bodyAngularVelocity.maxTorque = Vector3.new(mass / 6, mass / 3, mass / 6)
		else
			bodyVelocity.maxForce = Vector3.zero
			bodyAngularVelocity.maxTorque = Vector3.zero
		end

		for i, part in pairs(car:GetChildren()) do
			if part.Name == "Thruster" then
				UpdateThruster(part)
			end
		end
	end
	for i, v in pairs(car:GetChildren()) do
		if v:FindFirstChild("BodyThrust") then
			v.BodyThrust:Destroy()
		end
	end
	bodyVelocity:Destroy()
	bodyAngularVelocity:Destroy()
	camera.CameraType = oldCameraType
	userInputService.ModalEnabled = false
	script:Destroy()
end)

I think that’s it

it may work but it overshoots its speed and you’re mainly focusing on the lerp and my method worked with it just going forwards it didn’t work on turns

Oh yeah I might’ve done the rotation part wrong, change

rotation = rotation + math.rad((-stats.Speed.Value / 5) * movement.Y) * dt * 60

to

rotation = rotation + math.rad((-stats.Speed.Value / 5) * movement.Y * dt * 60)

and remove the dt * 60 calculation at the local speed = -car...... part

e.rbxm (53.3 KB)
doesn’t work

2 ways that i know of to make lerp consistent with FPS

  1. Set the Alpha to math.clamp(Alpha * DeltaTime * 60, 0.008, 1)
  2. Set the Alpha to 1 - math.exp(-Speed * DeltaTime) (trickier since the speed isn’t fraction of target now, if it doesn’t work set the -Speed to Speed, basically positive, and you may need to set it to a very high number)

the thing is, this script is a right script but when it comes to the turns going at the same pace regardless of fps it relentlessly fails

this is my approach to it

local lastTime = tick()
game:GetService("RunService").PreSimulation:Connect(function(_)

		local currentTime = tick()
		local deltaTime = currentTime - lastTime
		lastTime = currentTime
		local lerpAlpha = 0.075 * deltaTime * 60

	if car:FindFirstChild("DriveSeat") and character.Humanoid.SeatPart == car.DriveSeat then
		if IsGrounded() then
			if movement.Y ~= 0 then
				local velocity = car.Chassis.CFrame.lookVector * movement.Y * stats.Speed.Value
				-- Keep the equivalent scaling
				
				car.Chassis.Velocity = car.Chassis.Velocity:Lerp(velocity  ,lerpAlpha) 
				bodyVelocity.maxForce = Vector3.zero
			else
				bodyVelocity.maxForce = Vector3.new(mass / 1.1, mass / (2*x), mass / 1.1 ) 
			end
			local rotVelocity = car.Chassis.CFrame:vectorToWorldSpace(Vector3.new(movement.Y * stats.Speed.Value/ 50, 0, -car.Chassis.RotVelocity.Y * 5 * movement.Y))
			local speed = -car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity).unit.Z
			rotation = rotation + math.rad((-stats.Speed.Value / 5) * movement.Y)
			if math.abs(speed) > 0.1 then
				rotVelocity = rotVelocity + car.Chassis.CFrame:vectorToWorldSpace((Vector3.new(0, -movement.X * speed * stats.TurnSpeed.Value , 0)))
				bodyAngularVelocity.maxTorque = Vector3.zero
			else
				bodyAngularVelocity.maxTorque = Vector3.new(mass / x, mass/ 1.1 * x , mass/ 1.1) 
			end
			car.Chassis.RotVelocity = car.Chassis.RotVelocity:Lerp(rotVelocity  ,lerpAlpha)

		else
			bodyVelocity.maxForce = Vector3.zero
			bodyAngularVelocity.maxTorque = Vector3.zero
		end

		for i, part in pairs(car:GetChildren()) do
			if part.Name == "Thruster" then
				UpdateThruster(part)
			end
		end

	else
		for i, v in pairs(car:GetChildren()) do
			if v:FindFirstChild("BodyThrust") then
				v.BodyThrust:Destroy()
			end
		end
		script:Destroy()
		bodyVelocity:Destroy()
		bodyAngularVelocity:Destroy()
		camera.CameraType = oldCameraType
		userInputService.ModalEnabled = false
	end
	end)

it goes at the same pace when moved fowards and backwards but doesn’t when turns happen

Since it’s a Car, you should set it to Heartbeat instead of PreSimulation, Heartbeat is capped at 60FPS, so high FPS shouldn’t be an issue

yes, however when it comes to low fps it still does not go at the same pace vise versa