Lerping is one way to get an object to move toward another, although a simpler method is Vector.MoveTowards which I explain here. Lerping is good to know though and has other uses such as gradually changing one value into another. It’s easy to do wrong, so I’ll talk about the right way if you want to get a constant speed.
Lerping is one way of making an object go travel smoothly from one position to another. In the end I used Vector3.MoveTowards, but lerping is another option.
An example is my game Puzzledorf below. It’s grid-based movement, like the original Pokemon Gameboy games. I use Vector.MoveTowards to create smooth movement between moving from one grid space to the next, so that it looks seamless and it’s not obvious that it’s grid based movement. You could also, however, use Lerping.

Psuedo code:
progress += deltaTime;
Object = Lerp( startPosition, endPosition, progress );
When you lerp, you don’t pass in a speed. Instead, you pass in progress, also often written as t (though that can sound more cryptic).
What is progress? It’s a variable that represents how close the object is to the final position. If progress is 0.1, it’s 10% of the way there. If it’s 0.2, it’s 20% of the way there.
So Lerp is saying, “Move from the start position to the end position, and here’s how much progress I’ve made so far.”
Why do we add delta time to progress? Because that makes sure you’re always incrementing it by a tiny amount based on how much time has elapsed each frame.
Example program
public GameObject block;
public float speed = 10;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Vector3 startPosition = block.transform.position;
Vector3 endPosition = startPosition + new Vector3(10, 0, 0);
StartCoroutine(MovePieceLerp(block, startPosition, endPosition));
}
}
IEnumerator MovePieceLerp(GameObject piece, Vector3 startPosition, Vector3 end)
{
float progress = 0;
while (progress < 1)
{
// Normalized progress from 0-1 that represents movement from start to end
progress = Mathf.Clamp01(progress + Time.deltaTime * speed);
// Lerp from the provided start position to the end position
piece.transform.position = Vector3.Lerp(startPosition, end, progress);
yield return null;
}
}
We have a public game object called block. Pass any object you like in the inspector.
speed is a variable that will control the speed of our Lerp. Higher numbers will make the Lerp faster.
On Update, we start a Coroutine and create a few variables when we press the Space key. The variables are:
- A start position
- An end position
Which will be the start and end positions we use for moving our block object via Lerping.
For the startPosition we simply pass in the objects transform.position value.
For endPosition we add a Vector3(10, 0, 0) to our startPosition, which is telling the object to move 10 units to the right along the X-axis.
Then we start the coroutine MovePieceLerp() by passing in the object (block), the startPosition, and the endPosition. This kicks off our Lerping movement from startPosition to endPosition.
Now looking at our Coroutine in more detail:
IEnumerator MovePieceLerp(GameObject piece, Vector3 startPosition, Vector3 end)
{
float progress = 0;
while (progress < 1)
{
// Normalized progress from 0-1 that represents movement from start to end
progress = Mathf.Clamp01(progress + Time.deltaTime * speed);
// Lerp from the provided start position to the end position
piece.transform.position = Vector3.Lerp(startPosition, end, progress);
yield return null;
}
}
We create a float variable, called progress, which will track our movement progress. As the coroutine runs, we will increment progress until it reaches 1 (100% completion).
while (progress < 1)
This loop keeps running until our progress variable reaches 1, meaning the object has finished moving from the start to the end position. Every time the loops code gets completed one time, from top to bottom, that’s 1 loop, and the while part of the loop will check again be progress is 1 or not. If it is, the loop will stop. If not, the loop will run again.
// Normalized progress from 0-1 that represents movement from start to end progress = Mathf.Clamp01(progress + Time.deltaTime * speed);
Here we update progress. We add Time.deltaTime * speed to progress, which smoothly increases the value based on how much time has passed since the last frame. The speed is a multiplier that controls the speed of the movement (higher values mean faster movement).
We also use Mathf.Clamp01 to make sure progress stays within the range of 0 and 1. This ensures the movement doesn’t overshoot beyond the target position.
// Lerp from the provided start position to the end position piece.transform.position = Vector3.Lerp(startPosition, end, progress); yield return null;
Here, we use Vector3.Lerp to create our movement (also known as interpolation) between the startPosition and endPosition. The progress value controls how far along the movement is. For example:
- When
progress = 0, the object is at thestartPosition. - When
progress = 0.5, the object is halfway betweenstartandend. - When
progress = 1, the object reaches theendPosition.
At the end of the Coroutine, we return null. Coroutines always have to return something. Returning null pauses the coroutine until the next frame, allowing the movement to take place over time, rather than instantly. It makes sure the movement is spread across multiple frames, resulting in smooth animation.
Recap
Lerping (Linear Interpolation) is a method used to smoothly move an object between two points (start and end) based on a progress value. The progress variable represents how far along the movement is, ranging from 0 (at the start position) to 1 (at the end position). We use deltaTime to ensure that the progress increments smoothly each frame, and a speed multiplier to control how fast the movement occurs.
We calculate progress by adding Time.deltaTime * speed to it each frame. Using Mathf.Clamp01, we ensure that progress stays between 0 and 1, so the object arrives at its destination without overshooting.
To apply this in code, you start by setting a startPosition and endPosition. The coroutine runs in a loop, updating the object’s position by calling Vector3.Lerp(startPosition, endPosition, progress) until progress reaches 1, moving the object over time, frame by frame. This approach ensures smooth, linear movement.
Try it out. If you are still a bit unsure about Lerping, try looking at the Unity documentation here.
If you liked this article, please check out Puzzledorf to show your support. If you enjoy playing, leaving a review helps the games visibility on Steam.



Leave a comment