Multiple LERP?

I am having problems doing a LERP after another LERP. Only the last LERP is executed :frowning: What am I doing wrong?

function Update() { 

		childarr[0].transform.position = Vector3.Lerp(splinearr[0].transform.position, splinearr[1].transform.position, tid*smooth);
		childarr[0].transform.position = Vector3.Lerp(splinearr[1].transform.position, splinearr[2].transform.position, tid*smooth);
}

At the moment, you’re assigning the result of the first lerp to the objects position. After that you assign the second lerp to the objects position. Assigning a value to a position overwrites whatever value it had before, so only your second lerp is used.

You’ll need to specify how the two lerps are supposed to be combined into the position value of your object. Are they to be averaged, added, subtracted, or again lerped themselves? Only you can know ;).

I want the transformations to happen right after each other. I need to do more than just these two LERPs.

You’re performing one lerp and storing the result. Then you’re performing a different lerp and storing the result… over the result of the first lerp.

I think what you mean is something along the lines of…

temp = Lerp(var1, var2, amount1);
output = Lerp(temp, var 3, amount2);

or

output = Lerp( Lerp( var1, var2, amount1 ), var3, amount2);
1 Like

The above doesn’t work. When I do this, the object LERPS between the first and last position, but doesn’t come by the second position.

I want movement like this:

  • Lerp from A to B
  • Lerp from B to C
  • Lerp from C to D
  • Lerp from D to E

I am unsure how to do this :cry:

If you’re trying to do something along the lines of:

Bézier curve - Wikipedia (the animated examples are really illustrative on that page)

// Three points point1-3
position1 = Lerp(point1, point2, amount);
position2 = Lerp(point2, point3, amount);
output = Lerp(position1, position2, amount);

I just want to move the object, without any fancy interpolation.

Move in a straight line from point to point is what I want :slight_smile:

Sorry, I was overthinking the problem :smile:

Then there is no need to even think about more than one Lerp at a time.

Here’s a suggestion.

Make an array[ ] of locations and a counter “i” that starts at 0, then Lerp between array and array[i+1] and increase your Lerp amount from 0 to 1 over your time period. When the Lerp amount is 1, then reset it to 0, i++, and Lerp position between elements array and array[i+1] (checking to see if i+1 > array.length, of course).

I will try that, thank you :slight_smile:

Still can’t get this to work :frowning:

It still only does the last LERP.

	for (var i : int = 0; i < splinearr.length; i++) {
		if (i+1 > splinearr.length) {
			break;
		}
		childarr[0].transform.position = Vector3.Lerp(splinearr[i].transform.position, splinearr[i+1].transform.position, tid*smooth);
		tid = 0;
		
	}

You’re doing the same thing here that you were doing in the first place. You’re doing all the Lerps in a single frame, and storing them all in the same place.

A “for” loop isn’t an appropriate structure here, I’m afraid; you don’t want to iterate through the entire array in a single frame. You want to check each frame whether you want to go to the next pair of points, rather than doing the whole lot.

In each frame:

Check to see if the Lerp amount has reached 1.0. If it has, set it to zero and increment i - use the next pair of points from now on. If it hasn’t, add amount * Time.deltaTime and use the current pair of points.

I hope that makes sense, I’m bashing this out on my way out the door, I’ll check back a bit later!

Still having a bit problems here :slight_smile:

	if (tid * smooth <= 0) {
		var i : int = 0;
		for (var j : int = 0; j < childarr.length; j++) {
		childarr[j].transform.position = Vector3.Lerp(splinearr[i].transform.position, splinearr[i+1].transform.position, tid*smooth);		
		}} else
		if (tid * smooth >= 1.0) {
			i++;}	 
	}

shouldn’t this be working?

The code is, of course, in Update()…

private var i : int = 0;

function Update() {
   
   // Increase lerpAmount by a frame-rate independent value
   lerpAmount += lerpRate * Time.deltaTime;
   
   // Is lerpAmount over 1?
   if (lerpAmount > 1.0) {
      
      // Decrement lerpAmount to below 1.0 and increment i every time!   
      while (lerpAmount > 1.0) {
         lerpAmount--;
         i++;

      } // End while (lerpAmount > 1.0)

      // Have we gone past the end of splineArr?
      if (i + 1 > splineArr.length) {
      
         // Your code to handle reaching the end of splineArr here!
            
      } // End if (i + 1 > splineArr.length)
      
   } // End if (lerpAmount > 1.0)

   // Lerp using values from the array and lerpAmount   
   var lerpedPosition : Vector3 = Vector3.Lerp(splineArr[i], splineArr[i+1], lerpAmount);

}// End function Update()

I’m not sure what you were using childArr[ ] for in your code, but I hope what I wrote above is clear enough for you to adapt to your needs. It looks about right, although I have a strange blindness for the differences between < and > and keeping array indices straight that normally requires a bit of tweaking until I get things the right way around.

Don’t use Update. You can’t schedule events in Update (without a lot of ugly code hacking anyway) because it runs every frame. Use coroutines instead.

–Eric

Think I got this to work :slight_smile: I’ll post some code later on, I need to play around for a while now :slight_smile:

Thank you very much for clearing some important stuff in your replies, DMJ. Thank you others as well :slight_smile:

Thanks for the tip! I will look into this :slight_smile:

If people are still looking for an A to B to C back to A and so on lerp loop here is one:

    public Transform [] positions;
    public int i = 0;
    public float lerpAmount = 0;
    public float lerpSpeed = 1.2f;

    void Update () {

        //The lerpfloat should always be reset back to 0 otherwise you'd start teleporting.
        if (lerpAmount >= 1f)
            lerpAmount = 0;
        lerpAmount += lerpSpeed * Time.deltaTime;
        //Here the lerp from place to place takes place, I used %3 because I've 3 elements in my array, this way it keeps looping between these positions.
        transform.position = Vector3.Lerp (positions [i%3].position, positions [(i+1)%3].position, lerpAmount);
        //The code explains it self I guess.
        transform.LookAt (positions[(i+1)%3]);
        //since lerp never actually reaches its target you need to check for the distance and can't just say if the lerps final position is reached up "i" by 1.
        if (Vector3.Distance (transform.position, positions [(i + 1)%3].position) < 0.13333) {
            i ++;
            lerpAmount = 1;
        }
    }

Should be easy enough to transform into JS and use it for an A to B to C … to ENDPOINT script.

2 Likes