Unity lerp

Lerp in Unity

Before starting, I uploaded the files of this project to GitHub according to the process I have had until now, so you can download it from this link or open it with GitHub desktop software, which is better because you can easily get the next updates. The name of the file is LerpExamples, which is located in the Scenes folder.

What is Lerp first? It’s very simple to say that with Lerp you can create some kind of movement or animation. Of course, this animation has a linear mode, because Lerp only has the option of changing an object or several objects in the scene from the first point to the second point, or changing the current color of objects to the second color. To implement this change, other than the start and end points, you must specify when this work should be done. In general, the way to write Lerp is similar to the example below. Instead of those X’s in the below line, other things will be replaced, which I will explain below.

xxxx.Lerp (startingValue, endingValue, time);

Basically, the word Lerp, which is shortened from the Linear Interpolation, is a mathematical function that can be used to create new points between two specified points. For example, if you have two numbers and you want to know the number between them, it is enough to multiply the first number by ½ and add it to the second number which is also multiplied by ½. This can continue and eventually pinpoint many new points between those two initial numbers. Due to the mathematical nature of Lerp, it is placed in a class of Unity called Mathf, which is short for Math Function. I should also mention that in the Mathf class, a set of mathematical functions have been collected that are normally used in the development of games, such as logarithmic, trigonometric (sine, cosine, tangent, etc.), interpolation (Lerp types, etc.), square roots, exponents, etc.

According to the explanation above, now you have to replace those X’s with the name of the class in which the Lerp method is defined. Of course, apart from the Mathf class, other classes such as Vector3 and Color also define the Lerp method within themselves, which I will explain later.

Mathf.Lerp (startingValue, endingValue, time);

A very important point is the third variable or time, which is always between zero and one. It means that when this variable reaches the number of one, the Lerp will stop. For this reason, for example, for something to take four seconds, you must store the elapsed time from the beginning of the execution in a variable and then by dividing it by four to create numbers below one until finally it reaches one.

In the example below, the change of numbers between zero and ten is going to be shown in four seconds. So, first, I define the variables of the starting point, the ending point, and the time when that change occurs, i.e. lines 7, 8, and 9.

To have the elapsed time, I define the variable of line 11. Line 12 saves the result of running Lerp. But in line 14, because I thought it would be better to show the change of numbers in the form of integers during execution, I defined this variable to convert the decimal numbers stored in the variable of line 12 into integers. It is good to know that Lerp only accepts decimal numbers and is itself a decimal function.

using System;
using TMPro;
using UnityEngine;

public class lerp1stExample : MonoBehaviour
{
    float startingValue = 0f;
    float endingValue = 10f;
    float changingDuration = 4f;

    float timePast;
    float lerpValue;

    int toDisplayOnScreen;
    public TMP_Text myNumbersOnScreen;

    void Update()
    {
        lerpValue = Mathf.Lerp(startingValue, endingValue, timePast / changingDuration);
        timePast += Time.deltaTime;

        toDisplayOnScreen = (int)lerpValue;
        myNumbersOnScreen.text = toDisplayOnScreen.ToString() + "  Changing numbers";
    }
}

In line 15, in order to be able to access the text component in the TextMeshPro class to change the text inside, I have to define this variable. Its type is public, which allows me to connect the text game object I made in Unity to it, like the image below:

connect TMP

Also, read about Time.deltaTime in line 20 here.

But to move a cube placed at a point in three-dimensional space based on three xyz values, instead of the Mathf class, you should use the Vector3 class and its Larp method. Because Vector3 takes three values, it can be used for anything that has three values, such as rotation and scale.

using UnityEngine;

public class lerp2ndExample : MonoBehaviour
{
    Vector3 startingPosition;
    Vector3 endingPosition = new Vector3(2f, 0.1f, 0.2f);
    float changingDuration = 4f;
    float timePast;

    void Start()
    {
        startingPosition = transform.position;
    }
    void Update()
    {
        transform.position = Vector3.Lerp (startingPosition, endingPosition, timePast / changingDuration);
        timePast += Time.deltaTime;  
    }
}

In the example above, the motion of the cube is completely linear, but if you replace line 16 with the line below, the motion will first slow down, then accelerate, and finally slow down again, but the time will not change.

transform.position = Vector3.Lerp (startingPosition, endingPosition, Mathf.SmoothStep (0, 1, timePast / changingDuration));

In the above line, the Smoothstep method has been added. Another name for this method in animation software is ease in/ease out, which is usually used in the animation control section. In the graphs below, you can compare the difference of the parameter t or time in linear and curved modes. As I explained at the beginning of this post, the time variable is between zero and one, that’s why I set the graphs between zero and one. But why did I say parameter t two lines above, because it is usually written as f(t) = t, where t is the parameter of function f. This means that here you have a function that takes t as a parameter and returns a decimal value. In linear mode, our function is exactly f(t) = t, which means that whatever value you give to t, it returns the same value, but in Smoothstep mode, our function works as f(t) = 3t^2 – 2t^3. If you want to know more about Smoothstep, click here.

Linear vs Smoothstep

In Unity, apart from the Linear method, which is executed by default for the time variable in Lerp, and the Smoothstep method, which is super handy, there are other methods or functions that are not defined in the Mathf or Vector3 classes, such as Elastic Out, Parabola, and Bounce Out which you can see in the graphs below.

Linear vs Smoothstep

Well, now the question arises, how to write a method similar to the Bounce Out graph to control the time variable in Lerp. The answer is that you don’t need to write it because someone has already done it for you and you just have to add it to your class. On this GitHub page, a person named C.J. Kimberlin has shared 32 methods suitable for use in Unity, you just need to find the method you want and use it like the example below:

using UnityEngine;

public class lerp3rdExample : MonoBehaviour
{
    Vector3 startingPosition;
    Vector3 endingPosition = new Vector3(2f, -0.4f, 0.2f);
    float changingDuration = 4f;
    float timePast;

    void Start()
    {
        startingPosition = transform.position;
    }
    void Update()
    {
        transform.position = Vector3.Lerp(startingPosition, endingPosition, EaseOutBounce (0, 1, timePast / changingDuration));
        timePast += Time.deltaTime;
    }

    public static float EaseOutBounce(float start, float end, float value)
    {
        value /= 1f;
        end -= start;

        if (value < 1 / 2.75f)
            return end * (7.5625f * value * value) + start;

        if (value < 2 / 2.75f)
        {
            value -= 1.5f / 2.75f;
            return end * (7.5625f * value * value + .75f) + start;
        }

        if (value < 2.5 / 2.75)
        {
            value -= 2.25f / 2.75f;
            return end * (7.5625f * (value) * value + .9375f) + start;
        }

        value -= 2.625f / 2.75f;

        return end * (7.5625f * value * value + .984375f) + start;
    }
}

If you have downloaded the project file, this script is assigned to Cube-3 in the scene.

In addition, you are not limited to this number of methods and you can create new methods by combining two or more of these methods. Maybe if I get a chance, I will explain how to combine methods for use in Unity in another post.

Now the question arises whether there is a simpler way that does not limit us to a number of methods and we can more easily control the time variable in Lerp. For this purpose, there is a class called AnimationCurve in Unity that allows you to control the time through the shape you create. Of course, this is not all that this class does, but for now, this part is useful for you. Just like the example below, define a variable named curve or any other desired name in public type and add the Evaluate method to Lerp in line 18 to control the time. Now, if you check the script settings in the Inspector tab in Unity, you will see that the curve option has been added to it, and by clicking on it, a window will open that graphically allows you to create all kinds of linear or curved shapes.

using UnityEngine;

public class lerp4thExample : MonoBehaviour
{
    Vector3 startingPosition;
    Vector3 endingPosition = new Vector3(2f, -1f, 0.2f);
    float changingDuration = 4f;
    float timePast;

    public AnimationCurve curve;

    void Start()
    {
        startingPosition = transform.position;
    }
    void Update()
    {
        transform.position = Vector3.Lerp(startingPosition, endingPosition, curve.Evaluate(timePast / changingDuration));
        timePast += Time.deltaTime;
    }
}