Last active
October 19, 2021 04:43
-
-
Save Eideren/54276cbbc448cf89f58e3a1a3b9aa3d0 to your computer and use it in GitHub Desktop.
A replacement for the very common ``v = lerp(v, t, deltaTime)``, this one fixes the framerate dependant issue of the former while still providing easing in when close to target. Or just look at https://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/ instead
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example usage: | |
float dist = MathF.Abs( target - current ); | |
current = Lerp( target, current, MoveToZeroEased( dist, deltaTime ) / dist ); | |
/// <summary> | |
/// Moves <paramref name="distance"/> towards zero, the further away it is the larger the displacement. | |
/// Framerate independent. | |
/// </summary> | |
/// <param name="distance">The value you want to move towards zero</param> | |
/// <param name="timeDelta">The time between last and current call, multiply it to go faster</param> | |
/// <param name="easingRange">A constant which controls the speed increase per distance curve</param> | |
/// <remarks> | |
/// Time taken to travel is non-linear so for 100 units it'll take 10 sec but 200 is 14.1 sec. | |
/// </remarks> | |
static float MoveToZeroExp(float distance, float timeDelta, float easingRange = 2f) | |
{ | |
var sign = MathF.Sign( distance ); | |
double d = Math.Abs( distance ); | |
d = Math.Pow(d, 1d / easingRange); | |
d -= timeDelta; | |
d = d < 0d ? 0d : d; | |
d = Math.Pow(d, easingRange); | |
d *= sign; | |
return (float)d; | |
} | |
// Increasing 'easingRange' will increase the speed in a non-linear way, to work around this issue | |
// we compute a 4PL symmetrical sigmoidal curve to ensure the scale of dist and easingRange does not affect the timeDelta/speed. | |
// The precision of this curve falls off fast outside of the [1.5,8] range but that shouldn't matter a whole lot as | |
// the function does not guarantee any specific time to completion and it still will produce framerate independent result | |
static float FixedSpeedGivenRange(float dist, float easingRange) | |
{ | |
return dist * (1.848007f + 55.561453f / (1f + MathF.Pow(easingRange / 1.252288f, 3.513108f))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment