LERP for Fun and Profit
Updating and fixing a massive amount of bugs in “Super Panda Adventure Tour” has been quite the experience. On one hand, I’ve been neglecting my Flagship game. On the other, I was just learning Unity3D, and while a pretty good programmer, was not good at Unity. LERP is also for math geeks. Something which I am far from. It stands for Linear Interpolation, whatever that is. It basically finds a vector from start to destination and gets the object there in X time.

I first learned the errors of my ways when revisiting the Spike Traps in Super Panda. You see, they’d go up and down, but would incrementally grow forever slower the closer they got too the destination. To compensate, I’d check if Y was “close” to the destination by 0.03 units. If so, great, the spikes could now reverse direction. In code the wrong way looked like this:
transform.position = Vector3.Lerp(transform.position, _endPosition, speed*Time.deltaTime);
According to the Unity guides themselves, this was how it was done, but to my dismay, wrong. The proper way to get LERPy is the following:
float timeElapsed = Time.time - _startTime;
float percentageComplete = timeElapsed / LERPTime;
transform.position = Vector3.Lerp (_startPosition, _endPosition, percentageComplete);
You essentially grab the time you start the LERP in _startTime, calculate time elapsed, divide into the number of seconds you want the LERP to take (LERPTime) and get the percentage complete.
You then feed the start position and destination into the LERP function along with completion percentage. Once the percentage reaches above 1.0f, the LERP is done and you can stop it with a boolian test. See below for the source code for the Spike Trap controller.
The end result are smoother spike traps. I can set them to take 0.2 seconds or a painful 5 seconds to deploy/retract. Add in a random wait timer and you have some seriously painful times ahead. But that’s the fun part of making games, creative ways to torture and kill the player.
Super Panda Adventure Tour will have a lot of additional traps and fun things to make the journey tougher.
The code
As promised here is the full source for the Traps controller to use in your own games. Granted, there’s still cleanup and optimizations to be done, but that’s for another day.
public class SpikesController : MonoBehaviour { enum Directions { up, down } [SerializeField] Directions direction; [SerializeField] private float travelLength = 1f; [SerializeField] private float speed = 1.1f; // how many seconds to deploy. [SerializeField] private float minDelay = 0.5f; [SerializeField] private float maxDelay = 4f; private Vector3 startPosition; private Vector3 targetPosition; private Vector3 topPosition; private float lerpStarted; private bool isMove = true; private float y; // Use this for initialization void Start () { direction = Directions.up; startPosition = transform.position; topPosition = startPosition + Vector3.up * travelLength; /* topPosition = new Vector3( transform.position.x, transform.position.y + travelLength, transform.position.z); */ targetPosition = topPosition; } /* *********************************************************** */ void FixedUpdate () { if (isMove) MoveNPC(); } void TimeDelay(){ isMove = true; lerpStarted = Time.time; } /* *********************************************************** */ private void MoveNPC() { float timeSinceStarted = Time.time - lerpStarted; float percentageComplete = timeSinceStarted / speed; switch (direction) { case Directions.up: transform.position = Vector3.Lerp(startPosition, targetPosition, percentageComplete); if (percentageComplete >= 1f) { targetPosition = startPosition; direction = Directions.down; isMove = false; Invoke("TimeDelay", Random.Range(minDelay, maxDelay)); } break; case Directions.down: transform.position = Vector3.Lerp(topPosition, targetPosition, percentageComplete); if (percentageComplete >= 1f) { targetPosition = topPosition; direction = Directions.up; isMove = false; Invoke("TimeDelay", Random.Range(minDelay, maxDelay)); } break; } } }