- Home /
How to get inverse of a lerp function
speed = Mathf.Lerp(speed, goalSpeed, time);
This code increases speed close to goalSpeed almost immediately and then slows down as it approaches it. How can I flip this around so that it accelerates slowly and then begins to speed up as it approaches it?
This is probably a simple answer, I can't wrap my head around it.
Answer by Eric5h5 · Mar 26, 2013 at 10:30 PM
That's not what the code does actually. The third parameter in Lerp is a float between 0 and 1, so if you increase the value linearly then there is no slowdown (and that is in fact what lerp means...*L*inear Int*erp*olation). I'm assuming you're referring to using Time.deltaTime in the third parameter, which is a sort of "freak" usage. While that can be useful on occasion, it's better to use it "correctly" so you have proper control over the behavior.
For example, you can make an Ease function:
enum EaseType {None, In, Out, InOut}
function Ease (t : float, easeType : EaseType) : float {
if (easeType == EaseType.None)
return t;
else if (easeType == EaseType.In)
return Mathf.Lerp (0.0, 1.0, 1.0 - Mathf.Cos (t * Mathf.PI * .5));
else if (easeType == EaseType.Out)
return Mathf.Lerp (0.0, 1.0, Mathf.Sin (t * Mathf.PI * .5));
else
return Mathf.SmoothStep (0.0, 1.0, t);
}
Then use that in Lerp:
var easeType = EaseType.In;
function Start () {
var t = 0.0;
while (t < 1.0) {
t += Time.deltaTime * .5;
transform.position.x = Mathf.Lerp (0.0, 5.0, Ease (t, easeType));
yield;
}
}
That code will move the x position from 0 to 5 over 2 seconds in a manner depending on what you change the easeType variable to: straight linear movement, ease in, ease out, or both in and out.
Thanks Eric. That seems a handy static function so I saved it to my project. I also added EaseInExpo as an additional option to $$anonymous$$e, which is what I really was after:
else if (easeType == EaseType.InExpo)
return $$anonymous$$athf.Pow( 2, 10 * (t/1 - 1) );
Technically, what the code I originally posted does IS what I said it does: it does increase the speed towards goalSpeed so that it starts fast and slows down over time. It may not be correct but it's easy. I guess I was just wondering if there was a similarly easy method for what I was looking for. But this works too. :)
Not to nitpick, but the code as originally posted would only slow down if you use Time.deltaTime as the third parameter. With just "time" (presumably Time.time), it doesn't. Also, t/1 is always just t, so you don't need that part.
it's not using Time.deltaTime, it's using a while loop with the normalized difference between two values.
Ah, you're right. I simplified it to to: $$anonymous$$athf.Pow( 2, 10 * t - 10 );
It's been a while since this answer was posted, but dude, you saved my life. XD
I managed to do something with this on a character movement using touch controls, all because the GetAxis behavior is totally different from the touch one. But it's done now! :)
Haha I just wanted to get this out, thanks again (even though it was an indirect help lol).
Cheers!
You can also use AnimationCurve to do this kind of thing. Evaluating an animation curve which ranges from 0-1 using a lerp gives you a finer degree of control (you can basically draw your own easing curve in the inspector). It's less processor intensive than using math functions such as power etc.
https://docs.unity3d.com/ScriptReference/AnimationCurve.html