3 min read

An obvious use for .Lerp() that does NOT involve animation

I recently learned something about another common function — good old .Lerp() — that I wanted to share with you, because if you’re like me you’ll find it so obvious in hindsight you’ll probably kick yourself for not using it more.
An obvious use for .Lerp() that does NOT involve animation

I’m two years into building Spacefreighter and I’ve used all sorts of C# math functions in Unity for all sorts of things: Random.Range() for rotations and spawns, Sin(Time.time) for oscillation, and the ubiquitious Mathf.PI() for all things circular, just for starters. But I recently learned something about another common function — good old .Lerp() — that I wanted to share with you, because if you’re like me you’ll find it so obvious in hindsight you’ll probably kick yourself for not using it more.

I found this trick useful for teaching SF's shipBrains where to go.

.Lerp() and its cousin .Slerp() are often used for animation. Usually, this is performed over time, in an Update or FixedUpdate function. For example, Spacefreighter’s menus use Lerp to ease in and out in a pleasing way.

The general form of a Lerp function returns a value between value A and value B defined by some interpolation value t, as follows:

In math terms, this is just returning a + (b-a) * t … easy. The value of t is clamped from [0,1], and this fact makes Lerp useful in frame-by-frame functions, incrementing t by a small value each frame to smoothly transition a value (a position or rotation) from state A toward state B over time. You can see how this would be useful for a rotation of a cannon towards a target, for example… you want a smooth turn, not a snap.

The goofy name of this function is really just a portmanteau of linear and interpolation, which is exactly what’s going on in the above example. In that name, we see a clue for another way to use Lerp — getting a Gameobject near, but not quite all the way to another object.

In Spacefreighter, for example, NPC ships have an AI that determines which enemy each ship should attack, and then sends the NPC ship towards its target using a pathfinding algorithm.

But setting the NPC algorithm’s destination to be the transform of the target ship resulted in a bunch of awkward ramming and bunching up — each ship would try to occupy the same space as its duellist.

Rather than blobbing up, I wanted the ships to intelligently strafe and circle each other. So, they needed to find their way to a point near, but not quite all the way to their enemies.

After constructing spheres with radii and tolerances and trying out some very over-engineered solutions, I realized that I could do this with one line of code, thanks to Lerp.

Simply replace the target transform position as the destination in the path calculation…

…with a Lerp between the NPC ship and its target. This approach even makes it easy to define how close we want to get with a single float. For example, to order the NPC to get 75% of the way to the target before seeking a new destination, I can modify the destination argument to the Lerp instead:

Brilliant. And that percent-to-target value is easily configurable too. That’s great for maintenance and playtest tweaking — important considerations for game AI.

The ships get close to the target, but their destination (green line) never reaches it fully. As intended!

Even though it’s mentioned in the docs, this use of .Lerp() isn’t one I see discussed too often on forums, where most threads focus on its animation potential. This might be because the docs point you at using it for frame-by-frame iteration and call the interpolation variable “t” (suggesting time) rather than “x” (suggesting position). But finding a point on a line x% between two points is precisely what the function is designed to do. Bottom line: Lerp is more than just an animation tool — you can use it to linearly interpolate, after all!

Kind of makes me wonder… what other functions have powerful, handy uses I’ve yet to discover or glossed over? Know of any? Head over to the Spacefreighter discord or hit me up on Twitter @mikeyoung44 and let me know.