Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

How to gradually scale an object between different sizes.

Discussion in 'Scripting' started by sonicbelmont, Jun 3, 2022.

  1. sonicbelmont

    sonicbelmont

    Joined:
    Jun 3, 2022
    Posts:
    2
    I've spent the past few hours trying different ways of getting a gradual change in size, but unfortunately I'm stuck. I can change the object between these sizes fine, I just want it to change over a few seconds instead of instantly.

    Code (CSharp):
    1. void SelectSize ()
    2.     {
    3.         if (selectedSize == 0)
    4.         {
    5.  
    6.             transform.localScale = new Vector3(0.15f, 0.15f, 0.15f);
    7.  
    8.         } else if (selectedSize == 1)
    9.         {
    10.  
    11.             transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
    12.  
    13.         } else if (selectedSize == 2)
    14.         {
    15.  
    16.             transform.localScale = new Vector3(1f, 1f, 1f);
    17.  
    18.         }
    19.     }
     
  2. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,739
    i would do it with a coroutine
    Code (CSharp):
    1.  
    2. private IEnumerator ScaleOverTime(float duration, float scale) {
    3.     var startScale = transform.localScale;
    4.     var endScale = Vector3.one * scale;
    5.     var elapsed = 0f;
    6.  
    7.     while (elapsed < duration) {
    8.         var t = elapsed / duration;
    9.         transform.localScale = Vector3.Lerp(startScale, endScale, t);
    10.         elapsed += Time.deltaTime;
    11.         yield return null;
    12.     }
    13.  
    14.     transform.localScale = endScale;
    15. }
    then when you need to call it you can just do
    Code (CSharp):
    1. StartCoroutine(ScaleOverTime(2f, 0.5f));
    which would scale it to 0.5 scale over 2 seconds.
     
    sonicbelmont likes this.
  3. sonicbelmont

    sonicbelmont

    Joined:
    Jun 3, 2022
    Posts:
    2
    This works fantastic, thank you for making it so easy to edit and manipulate. Very very appreciated.
     
  4. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,739
    a nice little trick you can do to expand on it, is use a AnimationCurve
    Code (CSharp):
    1.     [SerializeField] private AnimationCurve _scaleCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
    2.    
    3.     private IEnumerator ScaleOverTime(float duration, float scale) {
    4.         var startScale = transform.localScale;
    5.         var endScale = Vector3.one * scale;
    6.         var elapsed = 0f;
    7.         while (elapsed < duration) {
    8.             var t = _scaleCurve.Evaluate(elapsed / duration);
    9.             transform.localScale = Vector3.Lerp(startScale, endScale, t);
    10.             elapsed += Time.deltaTime;
    11.             yield return null;
    12.         }
    13.         transform.localScale = endScale;
    14.     }
    15.  
    this lets you do stuff like have it slow down near the end, or even let you give it a little bounce to it by editing the curve in the inspector
     
    sonicbelmont and Kurt-Dekker like this.
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,962
    While I dig how Passer whipped out a quick little solution like that, gotta also keep in mind it might be useful to get familiar with tweening packages like LeanTween, DOTween or ITween, which are made for this stuff and minimum of coding.
     
    sonicbelmont likes this.