Coroutine wont execute a second while statement to lerp object back?

Hello guys! I’ve been struggling to get my object to lerp towards a wanted position and back. I learned that Lerping an objects towards a position will nevet get it to be at the exact position, but ~x.999, so I’m comparing the distance between the start and endpoint with a small float, if the distance is bigger then I lerp.

I am also trying to use Coroutines and I’m having trouble so far when running two while statemets. When trying my methods out, my object will move towards the endPoint x position, but somehow the coroutine wont execute my second while loop which is meant to bring it back to it’s original starting point. It DOES NOT print the “SECOND SEQUENCE RUNS” log at all and skips to the finished coroutine one. Is my logic flawed? Could anyone please take a look at my code and guide me on the right path? Thank you!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lerp : MonoBehaviour
{

    [SerializeField] private GameObject gameObject;
    [SerializeField] private GameObject endPoint;

    private Transform startPoint;
    private Vector3 moveVector;
    public float speed = 5.0f;

    void Awake(){
        startPoint = gameObject.transform;
    }
    void Start()
    {
        StartCoroutine(LerpObject());
    }


    private IEnumerator LerpObject(){
        Debug.Log("STARTED COROUTINE");
        yield return new WaitForSeconds(1);
        while(endPoint.transform.position.x - gameObject.transform.position.x > 0.05f){
            Debug.Log("FIRST RUNS");
            moveVector = Vector3.Lerp(gameObject.transform.localPosition, endPoint.transform.localPosition, speed * Time.deltaTime);
            gameObject.transform.position = moveVector;
            yield return null;
        }
        Debug.Log("PAUSE");

        yield return new WaitForSeconds(2);

        while(gameObject.transform.position.x - startPoint.position.x > 0.05f){
            Debug.Log("SECOND SEQUENCE RUNS");
            moveVector = Vector3.Lerp(gameObject.transform.localPosition, startPoint.transform.localPosition, speed * Time.deltaTime);
            gameObject.transform.position = moveVector;
            yield return null;
        }


        Debug.Log("FINISHED COROUTINE");
    }
}

Why not just use Vector3.MoveTowards() instead? That way you can easily keep control of the velocity throughout, rather than inferring it from that term you call “speed”, which certainly is NOT speed when multiplied by Time.deltaTime and used as the third argument to Lerp().

Also, for deciding closeness to goal, use Mathf.Abs() otherwise it won’t work in one direction, eg x1 is always greater than x2.

I am aware the argument is not “speed”, but a point halving the two positions, but I was not sure what to name it and wanted something quick. Also what I am doing right now is making a scene comparing Vector3.Lerp(), MoveTowards and SmoothDamp between two points, hence I want to know how to do all three of them for my own “studies”.

I didn’t know about Mathf.Abs(), that seems extremely useful so thanks for that! My while loop still won’t run sadly :confused:

1 Like

Time to figure out why! Here is exactly how… it’s easy:

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3

This line

will NOT save your start position. All you do is storing a reference to your own object. So when you use that object reference and grab its position in your second while loop, you get the current position of your own object and not the starting position of your object. You should have stored the position when your script starts and not a reference to its own transform component.

So you should change your startPoint delcaration to

private Vector3 startPoint;

and store your starting position in Awake:

void Awake()
{
    startPoint = transform.localPosition;
}

Though as Kurt said, it would make more sense to use MoveTowards. Or if you want to have some kind of smoothing, use lerp the correct way by providing a fix start and end position and move the t value from 0 to 1. That way you can apply any kind of smoothing you like to your t value. Though using the current position as start value won’t be a linear interpolation.