Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Equivalent to Lerp or SmoothStep but with custom curves?

Discussion in 'Scripting' started by rrh, Feb 22, 2014.

  1. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    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?
     
  2. AlwaysSunny

    AlwaysSunny

    Joined:
    Sep 15, 2011
    Posts:
    260
    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.
     
    Last edited: Feb 22, 2014
    LordCafe and ericbegue like this.
  3. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    Thanks, I hadn't played with AnimationCurve before. It does look very promising.
     
  4. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Works well but will frequently crash if curves are edited in play mode.
     
  5. Brian-Stone

    Brian-Stone

    Joined:
    Jun 9, 2012
    Posts:
    222
    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.
     
  6. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    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:

    Code (csharp):
    1.  
    2. /// <summary>
    3. /// Lerping curves with different characteristics. Not clamped, only inputs between 0 and 1
    4. /// </summary>
    5. public static class LerpCurves{
    6.     //verify plots by inserting the commented functions into this plotter https://rechneronline.de/function-graphs/
    7.     //Cosinus soft in soft out from 0F to 1F. Coroutine useage example:
    8.     //    float time    = 1F;
    9.     //    float timer    = 0F;
    10.     //    while(timer < time){
    11.     //        float lerpFactor =    LerpCurves.SoftestInSoftOut01(timer/time);
    12.     //        image.color = new Color(1F,1F,1F,lerpFactor); //Do something with lerpFactor e.g. this creates a fade in
    13.     //        yield return null;
    14.     //        timer += Time.deltaTime;
    15.     //    }
    16.     //    image.color = new Color(1F,1F,1F,1F); //fully finish the lerp at the end
    17.  
    18.     public    static float SofterInSofterOut01    ( float valueFrom0to1) { return                    (-Mathf.Cos(valueFrom0to1 * Mathf.PI))*0.5F+0.5F;        }    //    ( cos(x*pi)*0.5+0.5)
    19.     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)
    20.     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
    21.     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
    22.  
    23.     //pretty much the same as SofterInSofterOut
    24.     public    static float SmoothStep01            ( float valueFrom0to1) { return        valueFrom0to1*valueFrom0to1*(3-2*valueFrom0to1);                    }    //     (x*x * (3 - 2*x))
    25.     public    static float SmoothStep10            ( float valueFrom0to1) { return    1F- valueFrom0to1*valueFrom0to1*(3-2*valueFrom0to1);                    }    //    1-(x*x * (3 - 2*x))
    26.  
    27.     //Symmetric, SoftestInSoftOut is not
    28.     public    static float SmootherStep01            ( float valueFrom0to1) { return        valueFrom0to1*valueFrom0to1*valueFrom0to1*(valueFrom0to1*(6F*valueFrom0to1-15F)+10F);    }    //     x*x*x * (x* (6*x - 15) + 10)
    29.     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)
    30.  
    31.     public    static float Linear01                ( float valueFrom0to1) { return        valueFrom0to1;                                                        }    //        x
    32.  
    33.     public    static float SoftInHardOut01        ( float valueFrom0to1) { return        Mathf.Pow(valueFrom0to1,3);                                        }    //        x^3
    34.     public    static float SoftInHardOut10        ( float valueFrom0to1) { return        1-Mathf.Pow(valueFrom0to1,3);                                        }    //    1-   x^3
    35.     public    static float HardInSoftOut01        ( float valueFrom0to1) { return        1-Mathf.Pow(1-valueFrom0to1,3);                                        }    //     1-(1-x)^3
    36.     public    static float HardInSoftOut10        ( float valueFrom0to1) { return        Mathf.Pow(1-valueFrom0to1,3);                                        }    //    (1-x)^3
    37. }
    38.  
     
    Last edited: Feb 20, 2022
  7. glenneroo

    glenneroo

    Joined:
    Oct 27, 2016
    Posts:
    231
    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!
     
    Marrt likes this.
  8. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Thanks, i changed the original code above
     
  9. aaronrums

    aaronrums

    Joined:
    Jan 9, 2021
    Posts:
    3
    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?
     
  10. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    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.

    I edited my post above, but i didn't test them, but i checked the graphs
    https://www.desmos.com/calculator/hm5xbp7qi4
     
    Last edited: Feb 20, 2022