Hello, fellow enthusiasts. I am in the urge of enlightenment! How can delta time be tied with a function that is running every frame to make the function scale accordingly? Let me show You what I mean:
The higher the frame rate the stiffer it gets. I am aiming to make it as similar as possible no matter the frame rate. I can not figure out what to do with delta time to get the best results.
local RunService = game:GetService("RunService")
local camera = workspace.CurrentCamera
local cameraCharacter = camera:WaitForChild("CameraCharacter")
RunService.RenderStepped:Connect(function(deltaTime)
-- Just +, -, *, / a by delta time does little to no difference
local a = 0.5
local lookVector0 = cameraCharacter.PrimaryPart.CFrame.LookVector
local lookVector1 = camera.CFrame.LookVector
local position = camera.CFrame.Position
local lookVector = lookVector0:Lerp(lookVector1, a)
local cFrame = CFrame.new(position, position + lookVector)
cameraCharacter.PrimaryPart.CFrame = cFrame
end)
Thank You for suggesting. These are the results when a = 0.99 ^ (1 / deltaTime): 30 fps 240 fps
It is not perfect but it does look more accurate. There might be a better way.
I am a colleague of @LeikaZ. And since he is sleeping… Because it is 03:00… Anyways. The lerp is very slow when multiplying deltaTime by values from 0 to 1. So the variable would end up something like a = 2 * deltaTime. This would mean that a could get higher than 1, therefore mess up the lerp. I have adjusted the variable to a = 0.5 * (1 - deltaTime). But even then the results were far from perfect: https://gyazo.com/44bda1eddeda61a8f626b6167298fd32 https://gyazo.com/62fd180d29b5ff54f3821b306249ffa5
i had a similar problem but since im bad at math i just took a large number (like if i did .1 i’d do 100 or something) and then multiplied by delta time, it takes some experimenting but it might help??
I believe changing a to a / (1/deltaTime)/maxFPS should do the trick. If the game is running at 240 fps and deltatime is 1/240 this should yield 240/maxFPS so an a of 0.5/1. If the game is running at half speed (120/240) you’ll get an a of 0.5/0.5 so 1 (twice the default in twice the time). Now you can clamp a like this to make sure it doesn’t lerp too far: math.clamp(a, 0, 1)
Thank You for replying, @Hexcede. Unfortunately, that does not seem to be the answer either… The lerp becomes too stiff on low FPS compared to mid/high FPS.
not into maths but, how about a = 0.2 * deltaTime * 30
meaning a would be around 0.2 when fps is 30, would be 0.1 when fps is 60, and 0.4 when fps is 15, lower the fps goes it would go towards 1, and eventualy exceed it, not sure how you’d keep the same effect under 8-10 fps but i’m sure nobody will be playing the game at that framerate… you can probably clamp it so it doesn’t go over 0.8 or 0.9 with a = math.min(0.2*deltaTime*30, 0.8).
otherwise i think lerp wouldn’t work.
I don’t know the answer, but I think we’d all have a better chance of getting it if we discussed the issue, rather than just say “try X”.
How is DeltaTime usually used?
When moving a part to be frame rate independent, you define a Speed in StudPerSecond. Because you know how much time has passed, you know how many studs it’ll have moved between frames.
-- Typed on mobile
RS.Heartbeat:Connect(function(DeltaTime)
Part.CFrame = Part.CFrame * CFrame.new(0,0,-Speed*DeltaTime)
end)
How can we apply this concept to lerps?
With OP’s current implementation, the lerps have no defined speed. DeltaTime therefore doesn’t give us useful information, because knowing how much time has passed doesn’t help if we don’t know how much it moves per time increment. They are therefore frame rate dependant.
The question is now how do we set a Speed for a lerp? OP clearly wants non-linear motion, so it gets even more complicated when you take that into account.
Let’s start with linear motion, and then we’ll figure out how we can implement an easing function.
I will post the answer here.
a - start value
b - result value
f - time a = lerp(a, b, 1 - f ^ dt)
It can be easily adjusted to a vector lerp: local currentVector = currentVector:Lerp(targetVector, 1 - howFastItLerps ^ deltaTime)
PERFECT ACCURACY
The answer is not entirely obvious. It’s actually:
a = lerp(a, b, 1 - f ^ dt)
…where f is the factor between 0 and 1 deciding how quickly it catches up, e.g. 0.25. In fact it works out that this is the remaining factor per second, so if it’s 0.25 it means it covers 75% of the remaining distance every second - independent of the framerate!
So why does this work? Since we cover 1 - f^dt, the remaining distance is f^dt. Over n frames, the remaining distance is thus (f^dt)^n. Again we can assume a steady framerate and that dt is equal to 1 / n . This gives the remaining distance over one second at n frames per second as (f^(1 / n))^n. If you know your powers, you know that (x^a)^b = x^ab. So we can simplify and see that the remaining distance after one second is f^1 = f. So it’s covered the same distance in one second regardless of the framerate!
This has the nice quality of being able to easily decide the percentage of the distance it covers every second. As before using f = 0.25 means it covers 75% of the distance regardless of the framerate, whereas trying to figure out the multiplier when just using f * dt to get it to cover 75% of the distance per second is very tricky (actually mathematically impossible, since it depends on the framerate), and probably just means guessing a few numbers and eyeballing it. Also as long as 0 < f < 1 , it will never overshoot.
Completely off topic but how is your client surpassing 60fps? Unless you’ve done some sort of modifying the Roblox client to remove the frame cap, I can only suspect you are somehow hooked up to physics updates (which according to my recollection go up to 240hz)…