Suppose I want a function like Mathf.Lerp or Mathf.SmoothStep where I pass in the from, to and t, but I want to define my own curves for how it converts?
Especially if I can do it visually somehow, like if there’s something in the editor that I can draw the curve it follow.
I can do visual curves with animations, but there’s a lot of extra stuff in there, and animation has to directly modify a value, while I just want to return a value from a function and then I can do what I want with it.
Is there something that works something like this?
Define a public AnimationCurve variable and you can edit the curve in the inspector.
Then instead of… Mathf.Lerp( foo, bar, t ); …call… myCurve.Evaluate( t ); edit: if you edit the curve to lie within a 0…1 range, you can do whatever you want to it programmatically to make it match your desired min/max. Looks like there are even functions to set the keys at runtime, if you need to.
Take a look at iTween, which is free. It may suit your needs. There are also a couple of visual editors for iTween. One of them is called iTween Multi Path, which is also free.
If someone stumbles upon this thread in order to get smoother lerps, i mostly use Mathf.Cos() lerps because they are smoother, here is a class for that:
/// <summary>
/// Lerping curves with different characteristics. Not clamped, only inputs between 0 and 1
/// </summary>
public static class LerpCurves{
//verify plots by inserting the commented functions into this plotter https://rechneronline.de/function-graphs/
//Cosinus soft in soft out from 0F to 1F. Coroutine useage example:
// float time = 1F;
// float timer = 0F;
// while(timer < time){
// float lerpFactor = LerpCurves.SoftestInSoftOut01(timer/time);
// image.color = new Color(1F,1F,1F,lerpFactor); //Do something with lerpFactor e.g. this creates a fade in
// yield return null;
// timer += Time.deltaTime;
// }
// image.color = new Color(1F,1F,1F,1F); //fully finish the lerp at the end
public static float SofterInSofterOut01 ( float valueFrom0to1) { return (-Mathf.Cos(valueFrom0to1 * Mathf.PI))*0.5F+0.5F; } // ( cos(x*pi)*0.5+0.5)
public static float SofterInSofterOut10 ( float valueFrom0to1) { return 1F - (-Mathf.Cos(valueFrom0to1 * Mathf.PI))*0.5F+0.5F; } // 1-( cos(x*pi)*0.5+0.5)
public static float SoftestInSoftOut01 ( float valueFrom0to1) { return Mathf.Pow( (-Mathf.Cos(valueFrom0to1 * Mathf.PI))*0.5F+0.5F, 2F); } // (-cos(x*pi)*0.5+0.5)^2
public static float SoftestInSoftOut10 ( float valueFrom0to1) { return 1F -Mathf.Pow( (-Mathf.Cos(valueFrom0to1 * Mathf.PI))*0.5F+0.5F, 2F); } // 1-(-cos(x*pi)*0.5+0.5)^2
//pretty much the same as SofterInSofterOut
public static float SmoothStep01 ( float valueFrom0to1) { return valueFrom0to1*valueFrom0to1*(3-2*valueFrom0to1); } // (x*x * (3 - 2*x))
public static float SmoothStep10 ( float valueFrom0to1) { return 1F- valueFrom0to1*valueFrom0to1*(3-2*valueFrom0to1); } // 1-(x*x * (3 - 2*x))
//Symmetric, SoftestInSoftOut is not
public static float SmootherStep01 ( float valueFrom0to1) { return valueFrom0to1*valueFrom0to1*valueFrom0to1*(valueFrom0to1*(6F*valueFrom0to1-15F)+10F); } // x*x*x * (x* (6*x - 15) + 10)
public static float SmootherStep10 ( float valueFrom0to1) { return 1F- valueFrom0to1*valueFrom0to1*valueFrom0to1*(valueFrom0to1*(6F*valueFrom0to1-15F)+10F); } // 1-x*x*x * (x* (6*x - 15) + 10)
public static float Linear01 ( float valueFrom0to1) { return valueFrom0to1; } // x
public static float SoftInHardOut01 ( float valueFrom0to1) { return Mathf.Pow(valueFrom0to1,3); } // x^3
public static float SoftInHardOut10 ( float valueFrom0to1) { return 1-Mathf.Pow(valueFrom0to1,3); } // 1- x^3
public static float HardInSoftOut01 ( float valueFrom0to1) { return 1-Mathf.Pow(1-valueFrom0to1,3); } // 1-(1-x)^3
public static float HardInSoftOut10 ( float valueFrom0to1) { return Mathf.Pow(1-valueFrom0to1,3); } // (1-x)^3
}
In case anybody else tries to use SofterInSofterOut and is wondering why only these two don’t work as expected, there’s a small typo. Just reverse these two function names and voila!
BTW thanks for these, they offer some nice diversity to regular Lerp and SmoothStep!
this is awesome! Thanks so much.
For me, the last 4 work in reverse, it appears that they return 1 and then move to 0. The final 4 functions all do this. Is this the intended behavior?
yup, this is an error, look at the comment on the right, there is the required function, just remove the “1-” in front of the 0 to 1 functions and you should be good.