Lerp value reaching destination BEFORE lerp ends?

Hi guys,

I have script that moves an object from a to b over a percentage value… The problem is, my object is reaching b way too early; give or take around 40%. This is causing my object to pause before the next action takes place which is not what I want. Any ideas on why this is happening?

Here’s my Lerp (inside coroutine):

   IEnumerator BullySquadMovement()
    {
        moveSpeed = .5f;
        float stopDis = 3f;
        float lerpTime = 1;
        float currentLerpTime = 0;
        float perc;
        bool reachedTarget = false;
        Vector2 enemyDirFromPlayer = (transform.position - player.position).normalized;
        Vector2 stopPosition = enemyDirFromPlayer * stopDis;
        
        while (true)
        {
            Debug.DrawLine(spawnPos, stopPosition, Color.blue);
            //Debug.DrawLine(transform.position, player.position);

            if (currentLerpTime < lerpTime)
            {
                currentLerpTime += Time.deltaTime;
            }
            else
            {
                reachedTarget = true;
            }

            perc = currentLerpTime / lerpTime;

            Debug.Log(perc);

            if (!reachedTarget)
            {
                transform.position = Vector3.Lerp(transform.position, stopPosition, perc); // Appears to reach target at .4 seconds
            }           
            else
            {
                transform.position = Vector2.MoveTowards(transform.position, player.position, moveSpeed * Time.deltaTime);
            }

            yield return null;
        }
    }

You’re lerping from the current position to the final position. You’re moving both the start point and the time.

Assuming you’re moving from x = 0 to x = 10, with a framerate of 10FPS, each frame would look like:

t: 0.0, x = 0,.0 lerp(0, 10, 0) = 0
t: 0.1, x = 0.0, lerp (0, 10, 0.1) = 1
t: 0.2, x = 1.0, lerp(1, 10, 0.2) = 2.8
t: 0.3, x = 2.8, lerp(2.8, 10, 0.3) = 4.96
t: 0.4, x = 4.96, lerp(4.96, 10, 0.4) = 6.976
t: 0.5, x = 6.976, lerp(6.976, 10, 0.5) = 8.488
t: 0.6, x = 8.488, lerp(8.499, 10, 0.6) = 9.3952

t: 1.0, x = 9.996371, lerp(9.996371, 10, 1) = 10

What’s happening is that you’re easing towards the stopPosition. If the distance is short, it will look like you’re at the end position too early, as from 60% of the time and onwards, you’re at >90% of the distance to the target.

A fun side effect here is that your code isn’t framerate independent. As your starting point gets closer to the end point for every frame, you get closer to the target faster with a high framerate. You’ll always get to exactly the target at 1 second, but the amount of time spent at almost the target increases exponentially with higher framerate.

To fix this, you’ll want to store your start position before you start the coroutine, and lerp from that instead of from your current position.

There’s also a bug in your stopPosition; surely it should be

Vector2 stopPosition = player.position + (enemyDirFromPlayer* stopDist);

rather than:

Vector2 stopPosition = (enemyDirFromPlayer* stopDist);

As it stands now, you’re moving to 3 meters away from the origin (0, 0, 0) rather than 3 meters away from the player.

EDIT:

also, you’re mixing between Vector2 and Vector3. If you have a 2D game, you should use Vector2 positions and Vector2.Lerp. If you have a 3D game, you should be doing Vector3 positions and Vector3.Lerp

1 Like

Omg I always make that mistake… I can’t believe I looked over that :o. I appreciate your in depth explanation, and yes, you’re correct about the stopPosition. Because my player is stationed at 0,0 I actually hadn’t noticed my error. Also thanks for the Vector3.Lerp spot!

Thanks again for your help.

P.S. Just realized you(?) are responsible for the ‘Lerp like a pro’ blog. Greatest blog ever! :stuck_out_tongue:

Not responsible! People keep assuming that - I just put it in my signature since I keep having to look it up whenever I need to link it.

I’ll add a disclaimer :stuck_out_tongue:

haha yeah I wasn’t sure if u did, I just made the assumption.