I recently came up with a nice, flexible, mini-framework for dealing with on-the-fly animations in Unity. It was birthed out of a need to create quick lerp animations, by means of coroutines, that are framerate-independent and easy to work with. I’ll give the complete implementation in this multi-part post.

## Background

### Coroutines

Coroutines are an entire post in themselves, so I won’t go into them here. I will say that they are about as close as you can get to multi-threaded coding in Unity, without actually being multi-threaded. This post will assume basic knowledge of them, so if you don’t know what they are, I suggest you brush up on them before continuing (here is a good starting point).

### Lerp

“Lerp” is short for “linear interpolation.” It’s a simple way to compute an intermediate value between two endpoints. Mathematically, it looks like this, for endpoints *a* and *b* and a fractional value of *t* between 0 and 1, inclusive:

You can see that when *t* = 0, the function will evaluate to *a*. When *t* = 1, the function will evaluate to *b*. And when *t* = 0.5, the function will evaluate to the midpoint between *a* and *b* ((a + b) / 2). You get the idea.

This general formula is used to lerp between values for a variety of types in Unity, including `float`

, `Vector2`

, `Vector3`

, and `Color`

(click here for a more exhaustive list).

A common misconception about the `Lerp`

variants in Unity is that they will perform animation. *This is not the case*, as a lerp function merely computes a value between *a* and *b* – that’s it. To animate using a lerp, it must be combined with the powers of a coroutine:

```
IEnumerator LerpForTenSeconds()
{
Vector3 start = Vector3.zero;
Vector3 end = new Vector3(0f, 5f, 3f);
float duration = 10f;
float startTime = Time.time;
float endTime = startTime + duration;
while (Time.time <= endTime)
{
float t = (Time.time - startTime) / duration;
transform.position = Vector3.Lerp(start, end, t);
yield return null;
}
}
```

Note that this is framerate-independent – that is, the animation will always take 10 seconds, no matter what. Unfortunately, there are a lot of examples out there (including in some Unity tutorials) that tell you to lerp with coroutines like this:

```
IEnumerator MoveToTarget()
{
Vector3 targetPosition = new Vector3(2f, 10f, 6f);
float someSpeedFactor = 1f;
while ((transform.position - targetPosition).magnitude > 0.01f)
{
transform.position = Vector3.Lerp(transform.position, targetPosition, someSpeedFactor * Time.deltaTime)
yield return null;
}
}
```

Unfortunately, this is neither “linear” interpolation nor is it truly framerate-independent, despite using `Lerp`

and `Time.deltaTime`

. Because the current position, which is changing, is used as the start value in the lerp, the interpolation becomes more like an exponential interpolation.

Now, how about that framerate-dependence? If you don’t believe me (it’s OK if you don’t – it took me a while to join the dark side too), imagine that your framerate were always very low, say 2 frames per second. Then, after 1 second, the object would have only 25% of its original journey left (half the distance would be traveled with each iteration, so 0.5^{2} = 0.25). Now, what if your framerate were 4 frames per second? After 1 second, the object would still have 32% of its original journey left (a quarter of the distance would be traveled with each iteration, so 0.75^{4} = 0.3164). Because the object would be in different positions after 1 second, solely due to framerate differences, this implementation is framerate-*de*pendent. For the mathematically inclined, refer to this plot, which represents the fraction of distance traveled after 1 second, as a function of framerate *f*, and note that it is clearly not constant.

## Coming up

Now that we’re on the same page, what if we wanted to do many animations similar to `LerpForTenSeconds()`

in our project but wanted to eliminate the need for writing all that boiler-plate code for looping and computing *t*? The next post will reveal a flexible implementation of a helper class to do just that.