简体   繁体   中英

Smoothly Lerp object based on button press Unity

Im creating a speedometer in Unity and I want my speedo arrow to smoothly lerp up to it's max angle based on the wither or not a button is pressed on. When the button is let go, I'd like the arrow to fall back to it's original rotation value.

However, I'm having issues trying to work out how to make my object lerp from its original position, to it's new position and back again. I've got it so when I press a button the objects jumps to a position, however, I need it to be smoother. Could someone please look over my code and point out what I need to do please?

float maxAngle = 100.0f;
float maxVel = 200.0f;
Quaternion rot0;
public float rotateValue;

// Use this for initialization
void Start () 
{
    rot0 = transform.localRotation;
}

// Update is called once per frame
void Update ()
{
    if(Input.GetKey(KeyCode.Space))
    {
        SetNeedle(rotateValue);
    }
}

void SetNeedle(float vel)
{
    var newAngle = vel * maxAngle / maxVel;

    transform.localRotation = Quaternion.Euler(newAngle,0,0) * rot0;


    float angle = Mathf.LerpAngle(minAngle, maxAngle, Time.time);
    transform.eulerAngles = new Vector3(0, angle, 0);
}

From the documentation :

static float Lerp(float from, float to, float t);
Interpolates between a and b by t. t is clamped between 0 and 1.

Which means t goes from 0% to 100%. When t == 0.5f the result will be the middle angle between from to to .

Hence, if the needle needs to be moved in a smooth and constant speed, you should do:

time += Time.deltaTime; // time is a private float defined out of this method
if(time >= 1.5f) // in this example the needle takes 1.5 seconds to get to its maximum position.
    time = 1.5f // this is just to avoid time growing to infinity.
float angle = Mathf.LerpAngle(from, to, time/1.5f); // time/1.5f will map the variation from 0% to 100%.

But that requires the from and to to be constant during the lerp fase. So what you need to do is the following:

  • when you press Space, set time = 0 , from = currentAngle and to = maxAngle ; Obviously this must be done only once during the key down event.
  • when you release Space, set time = 0 , from = currentAngle and to = 0 . Also do this only once.

All right?

You should use Time.deltaTime, not Time.time. That should make it move correctly.

EDIT: deltaTime won't solve the problem alone, however. Sorry I didn't fully read your code at first.

In order to smoothly move the needle, you need to know where the needle is currently, where it needs to go, and how much time has elapsed since the last time it moved.

We know how much time has elapsed with Time.deltaTime. But your code currently doesn't take into consideration where the needle is. float angle = Mathf.LerpAngle(minAngle, maxAngle, Time.deltaTime); will always evaluate to roughly the same value, so your needle will never move beyond a tiny bit.

What you should do instead is lerp from the needle's current position towards the maxAngle.

float angle = Mathf.LerpAngle(currentAngle, maxAngle, Time.deltaTime);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM