Home > Back-end >  Lerp brings object to unrelated position
Lerp brings object to unrelated position

Time:07-27

I've been trying to make a script that moves the selected object smoothly up and down, which seems simple enough, but I was pretty confused when my script kept putting the object in a weird Y position.

I finally got it to work, after trying half of the day, and then scrapping the code, but one question still remains unanswered in my head. Why does the following script not work?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spin : MonoBehaviour
{
    string UpOrDown;

    Vector3 originpos;
    Vector3 goalUp;
    Vector3 goalDown;

    void start()
    {
        originpos = transform.position;
        goalUp = originpos   new Vector3(0, 0.05f, 0);
        goalDown = originpos - new Vector3(0, 0.05f, 0);
        UpOrDown = "Up";
    }

    string TweenLerp(Vector3 destination, float time, string UpOrDownResult) {
        while (transform.position != destination)
        {
            transform.position = Vector3.Lerp(transform.position, destination, time);
        }
        return UpOrDownResult;
    }



    void Update()
    {
        if (UpOrDown == "Up")
            UpOrDown = TweenLerp(goalUp, 0.125f, "Down");
        else if (UpOrDown == "Down")
            UpOrDown = TweenLerp(goalDown, 0.125f, "Up");
    }
}

Sorry if the script seems kind of stupid or with crappy logic, im still kind of new to c#, unity and vectors, so trying to figure out how it works.

CodePudding user response:

so your code works fine, and everything is correct, the reason it's not working is that you called the Start function start(), lowercase, which makes unity not call it. To make this code work all you need is to substitute start() with Start().

Some extra notes to be aware of Lerp and the way you are using it: The way you're doing this animation does work, but not in the way that I think you intended, here's why: Lerp stands for linear interpolation, and the way it works is that you give a start value (transform.position in your case), an end value (destination), and a value (t) between 0 and 1 that indicates if your value should be more to the start or to the end if t = 0, the result will be the start value, if t = 1, the result will be the end value.

The reason why this works is that everytime you call this lerp function with a value grater than 0, the result value is bit closer to the destination. and if you keep doing this many and many times, eventually it'll get to the destination, but not with linear speed, it will start very fast and end very slow

In your code, you are repeatedly calling this function until the transform.position is equal to the destination using a parameter t called time, the problem is that this "time" value does NOT affect the time of the animation. Since you're doing all of the lerps to get to the destination in one single while loop, they all happen in the same frame, which means that this function is doing the same as transform.position = destination but with a lot of unnecessary Lerp calculations. Btw, if you set the time to 0 in this case you get an infinite loop and you'll need to restart unity.

If you want to have the animations actually happen thru some time and not in one single frame, you should call this Lerp in the Update, so that in each frame it moves a little bit. Your Uptade could look like this:

void Update()
    {
        if (transform.position == goalUp)
            UpOrDown = "Down";
        else if (transform.position == goalDown)
            UpOrDown = "Up";

        transform.position = Vector3.Lerp(transform.position, UpOrDown == "Up" ? goalUp : goalDown, time);
    }   

One more thing: this time parameter actually makes more sense interpreted as speed, since the lower the value of time, the slower the animation will happen.

Sorry for the size of the answer, hope I have helped!

  • Related