Search Unity

How to use Lerp???

Discussion in 'Scripting' started by nbg_yalta, Dec 25, 2019.

  1. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    In this example I'm trying to change object's scale over given time using coroutine but with no succes, Lerp is done a way faster than it should, why so?
    For example if target scale is 5 and duration is 3,
    lerp is complete when lerpTime (counter / time) is ~0.37 istead of 1
    What is wrong?
    Unity 2019.2.5
    Code (csharp):
    1.  
    2.     public Vector3 newScale = new Vector3(5, 5, 5);
    3.     public float duration = 3;
    4.     public Vector3 currentScale = Vector3.one;
    5.     public float counter;
    6.     [Range(0, 1)]
    7.     public float lerpTime;
    8.  
    9.     // Update is called once per frame
    10.     void Update()
    11.     {
    12.         if (Input.GetKeyDown(KeyCode.S))
    13.             StartCoroutine(Scale(newScale, duration));
    14.     }
    15.  
    16.     IEnumerator Scale(Vector3 target, float time)
    17.     {
    18.         while (counter < time)
    19.         {
    20.             counter += Time.deltaTime;
    21.             lerpTime = counter / time;
    22.  
    23.             currentScale = transform.localScale;
    24.             transform.localScale = Vector3.Lerp(transform.localScale, target, lerpTime);
    25.  
    26.             if (transform.localScale == newScale)
    27.                 Debug.Break();
    28.  
    29.             yield return null;
    30.         }
    31.     }
    32.  
     
    Last edited: Dec 25, 2019
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    Vector3.Lerp
    and
    Mathf.Lerp
    work analogously to each other.

    They take the third argument (which must go from 0.0f to 1.0f), and return a value equal between the first and the second argument.

    I'm having trouble tellling what you're trying to do exactly, but if you want something to scale up over time range, you want to do something like this:

    Code (csharp):
    1. float TimeRange = 4.5f;  // how long to change over
    2.  
    3. float time = 0.0f;
    4.  
    5. while(true)
    6. {
    7.   float fraction = time / TimeRange;
    8.  
    9.   time += Time.deltaTime;
    10.  
    11.   // now do your lerp, I'll keep it simple here
    12.   outputVector = Vector3.Lerp( startVector, endVector, fraction);
    13.  
    14.   // TODO: do what you want with outputVector here
    15.  
    16.   if (fraction >= 1.0f) break;
    17.  
    18.   yield return null;
    19. }
    EDIT: I had some typos above that I cleared up;

    The reason I structure it that way is to ensure the final reading is equal to endVector by ensuring the time doesn't end at something like 4.4995f or something.

    You may of course feed the
    transform.localScale
    value in, but keep in mind you are changing it every time, so it's hard for me to reason about what that will do. You probably want to make a copy of it BEFORE the loop, and tween from it to the final scale, but I'm not sure what you're doing exactly.
     
    nbg_yalta likes this.
  3. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    you lerp from current to target; if you want it to take exactly duration time, you need lerp from start to target
    tip: when the coroutine ends, do another assign of scale = target, since the lerp might over/undershoot by some tiny float value
     
    nbg_yalta likes this.