Search Unity

How do i fade a object in/out over time?

Discussion in 'Scripting' started by merlinmarijn, Oct 16, 2015.

Thread Status:
Not open for further replies.
  1. merlinmarijn

    merlinmarijn

    Joined:
    Aug 3, 2015
    Posts:
    44
    hi i want to make a object fade out over a unspecified amount of time i dont know how to do that i know it is with (time.deltatime) but i dont know to write it can someone help me with this?
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    I'll give you a little piece of code I've used for years to make transitions like this really straightforward.
    Code (csharp):
    1. IEnumerator DoAThingOverTime(Color start, Color end, float duration) {
    2. for (float t=0f;t<duration;t+=Time.deltaTime) {
    3. float normalizedTime = t/duration;
    4. //right here, you can now use normalizedTime as the third parameter in any Lerp from start to end
    5. someColorValue = Color.Lerp(start, end, normalizedTime);
    6. yield return null;
    7. }
    8. someColorValue = end; //without this, the value will end at something like 0.9992367
    9. }
    You can simply call StartCoroutine(DoAThingOverTime(x,y,1f) ); and it'll handle the transition.

    Does that help?
     
  3. merlinmarijn

    merlinmarijn

    Joined:
    Aug 3, 2015
    Posts:
    44
    thx this is what i was searching for :)
     
  4. Ciava

    Ciava

    Joined:
    Jun 1, 2018
    Posts:
    50
    Sorry for opening again this thread ... I am a noob ... I can't understand the:

    Code (CSharp):
    1. someColorValue = Color.Lerp(start, end, normalizedTime);
    part. What I have to do with "SomeColorValue"? Of course It's giving me an error!
     
  5. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    The person who posted that code didn't make any assumptions over exactly how the color would be used. So, the code just shows how to transition from one color to another color over time. It's assumed that upon every calculation of someColorValue, the color would be assigned to some visible object. For example, to the color of a sprite, or the color of a material.

    Anyway, this code just produces a color. Assign that color to the color property of whatever thing you're trying to change the color of.

    To specifically address the "error" you're getting, just put `var ` or `Color ` in front of someColorValue. The original code didn't bother to declare it, because often you won't be storing the value in a variable, you'd be assigning it directly to a color property of an object.
     
  6. Ciava

    Ciava

    Joined:
    Jun 1, 2018
    Posts:
    50
    Thanks Dgoyette!
    What I am trying to achieve is turning my attached gameobject from solid (255 alpha, I guess) to transparent (0 alpha I guess), before destroying it

    Code (CSharp):
    1. public float durata = 1f;
    2.    
    3.        private Color x, y;
    4.         Color someColorValue;
    5.  
    6.  
    7.     void Start() {
    8.        
    9.         x.a = 255f;
    10.         y.a = 0f;
    11.  
    12.     }
    13.  
    14.     void FixedUpdate () {
    15.  
    16.         StartCoroutine(DoAThingOverTime(x, y, 1f));
    17.     }
    18.  
    19.     public void EliminaScoreggia () {
    20.  
    21.         Destroy(gameObject);
    22.  
    23.     }
    24.  
    25.     public IEnumerator FadeOut (float dur) {
    26.  
    27.         for (float f = 1f; f >= -0.05f; f -= 0.05f) {
    28.  
    29.             Color color = rend.material.color;
    30.             color.a = f;
    31.             rend.material.color = color;
    32.             yield return new WaitForSeconds(0.05f);
    33.  
    34.         }
    35.  
    36.     }
    37.  
    38.  
    39.     IEnumerator DoAThingOverTime(Color start, Color end, float duration)
    40.     {
    41.         for (float t = 0f; t < duration; t += Time.deltaTime)
    42.         {
    43.             float normalizedTime = t / duration;
    44.             //right here, you can now use normalizedTime as the third parameter in any Lerp from start to end
    45.             someColorValue = Color.Lerp(start, end, normalizedTime);
    46.  
    47.             yield return null;
    48.         }
    49.          someColorValue = end; //without this, the value will end at something like 0.9992367
    50.     }
    Using this code ... I can't see no effect on my Gameobject! ;-\
     
  7. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    That depends on the material and what shader it's using. Some materials support transparency, while others don't. So in general it's pretty difficult to come up with a "works for everything" solution without knowing what material(s) you're using on your objects.

    However, if it's for UI objects, then there's an even simpler solution: Just add a CanvasGroup to your parent UI gameobject. That exposes an alpha value that you can lerp between 0 and 1 to fade it in/out.
     
  8. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    And you've confirmed that the material supports transparency? What shader are you using? If you manually adjust the material color's alpha in the Inspector, does it look the way you'd expect?
     
  9. Ciava

    Ciava

    Joined:
    Jun 1, 2018
    Posts:
    50
    Hey! :) Thanks for your support! I mixed together two tutorials and I found the right recipe for my needing!

    Code (CSharp):
    1. IEnumerator DoAThingOverTime(float duration)
    2.     {
    3.         for (float t = 0f; t < duration; t += Time.deltaTime)
    4.         {
    5.             Color c = rend.material.color;
    6.             c.a = c.a - 0.0001f;
    7.             rend.material.color = c;
    8.             yield return null;
    9.  
    10.         }
     
  10. Ciava

    Ciava

    Joined:
    Jun 1, 2018
    Posts:
    50
    Uhm, but now I have a new (of course!) problem
    I want to destroy object when Alpha is 0 but:

    Code (CSharp):
    1. if (c.a.Equals(0f))  {
    2.  
    3.                 Debug.Log("Alpha is  0");
    4.  
    5.             }
    6.  
    Does not work! :-\ Any Idea?
     
  11. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Checking for exact equality in this kind of situation can be an issue. Your alpha value is probably ending up either below zero, or some tiny fraction away from zero. It's also possible that floating point inaccuracy is prevent exactly equality.

    I'd check whether the value is <= some small amount instead of checking equality with zero.
     
  12. Ciava

    Ciava

    Joined:
    Jun 1, 2018
    Posts:
    50
    Hey! Thanks Again! Well My goal is REALLY stupid (fade away a "fart cloud") :D

    I did it like this:

    Code (CSharp):
    1. IEnumerator DoAThingOverTime(float duration)
    2.     {
    3.         for (float t = 0f; t < duration; t += Time.deltaTime)
    4.         {
    5.             Color c = rend.material.color;
    6.             Color fine = rend.material.color;
    7.             c.a = c.a - 0.0005f;
    8.             rend.material.color = c;
    9.            
    10.             yield return null;
    11.  
    12.             if (rend.material.color.a <= 0f)
    13.             {
    14.  
    15.                 EliminaScoreggia();
    16.             }
    17.  
    18.         }
    19.  
    20.        
    21.  
    22.     }
    IEnumerator DoAThingOverTime(float duration)
    {
    for (float t = 0f; t < duration; t += Time.deltaTime)
    {
    Color c = rend.material.color;
    Color fine = rend.material.color;
    c.a = c.a - 0.0005f;
    rend.material.color = c;

    yield return null;

    if (rend.material.color.a <= 0f)
    {

    EliminaScoreggia();
    }

    }



    }
     
  13. TeamSyntax

    TeamSyntax

    Joined:
    Aug 14, 2015
    Posts:
    2
    This is a necro-post, but for anyone looking for the answer in the future, here's how you do it.
    What you're trying to accomplish is a basic D = RT equation. You need to know how far apart your color vectors are from the target, since the values can be negative or positive. It's kind of confusing at first, but it's actually pretty simple. I whipped this up kinda quick for my current project, so the variable names may be confusing, but the equation still applies.

    I used fixedTime rather than deltaTime because I needed the equation to stay consistent. You could use deltaTime if you like, you would just need to adjust the function to update the equation per frame.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using System.Collections;
    5.  
    6. public class UI_FadeInOut : MonoBehaviour
    7. {
    8.     public Image targetImage;
    9.  
    10.     public Color[] finalColor;
    11.     public float[] fadeTime;
    12.  
    13.     void Start()
    14.     {
    15.         Fade(0);
    16.     }
    17.  
    18.     IEnumerator FadeColor(int _pos)
    19.     {
    20.         Color changePerSecond = GetChangePerSecond(targetImage.color, finalColor[_pos], fadeTime[_pos]);
    21.         float time = 0;
    22.         Color col = targetImage.color;
    23.  
    24.         while (targetImage.color != finalColor[_pos])
    25.         {
    26.             time += Time.fixedDeltaTime;
    27.             col = targetImage.color;
    28.  
    29.             // Add the color change to the current color
    30.             col += changePerSecond * Time.fixedDeltaTime;
    31.  
    32.             targetImage.color = col;
    33.  
    34.             // Just to make sure we end our coroutine
    35.             if(time >= fadeTime[_pos])
    36.             {
    37.                 targetImage.color = finalColor[_pos];
    38.             }
    39.  
    40.             yield return new WaitForFixedUpdate();
    41.         }
    42.  
    43.         Debug.Log("UI_FadeInOut :: COLOR FADE COMPLETE");
    44.         Fade(_pos == 0 ? 1 : 0);
    45.     }
    46.  
    47.     Color GetChangePerSecond(Color _currentColor, Color _target, float _endTime)
    48.     {
    49.         Color myColor = _currentColor;
    50.         Color targColor = _target;
    51.         Color distance = targColor - myColor;
    52.  
    53.  
    54.  
    55.         return distance/_endTime; // Returns the change needed per second
    56.     }
    57.  
    58.     /// <summary>
    59.     /// Fade the image color to a position on its Color array.
    60.     /// </summary>
    61.     /// <param name="_fadePosition"></param>
    62.     public void Fade(int _fadePosition)
    63.     {
    64.         StartCoroutine(FadeColor(_fadePosition));
    65.     }
    66. }
    67.  
     
    Last edited: Jan 16, 2022
  14. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    radoslawix and Gamadrila like this.
  15. TeamSyntax

    TeamSyntax

    Joined:
    Aug 14, 2015
    Posts:
    2
    I suppose it depends in what context you're using it. In a situation where it is impossible for there to be a conflict (like in my game) then it's perfectly usable. But, you are correct.

    I haven't had to use this, but would it not fix that issue if you use StopAllCoroutines(); before starting one?
     
  16. ordinov

    ordinov

    Joined:
    May 6, 2022
    Posts:
    1
    pretty nice method name, btw :D
     
Thread Status:
Not open for further replies.