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
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Light fades out but not back in

Discussion in 'Scripting' started by Pi_User5, Sep 27, 2016.

  1. Pi_User5

    Pi_User5

    Joined:
    Sep 27, 2016
    Posts:
    4
    I have a main light in my game and I want the light to slowly fade out over time and then fade back to full intensity and then fade back out and etc. so something similar to night and day. Sadly, the code I have right now fades the light out like I want it to but it goes back to starting intensity instead of fading back in. This is what my code is right now. Any help would be greatly appreciated.

    void Update () {
    if (mainLight.intensity <= 1) {
    #if DEBUG
    print (mainLight.intensity);
    #endif
    mainLight.intensity = Mathf.Lerp(1,0,Time.time / 5);
    }
    if (mainLight.intensity <= 0) {
    #if DEBUG
    print ("Light intensity is 0");
    #endif
    mainLight.intensity = Mathf.Lerp(0,1,Time.time / 5);
    }
    }
     
  2. CloudKid

    CloudKid

    Joined:
    Dec 13, 2015
    Posts:
    207
    Hey there friend. To make our life easier can you, next time, use the code tag for you code.

    So you problem is that you are confusing Time.time which is the time in seconds since the start of the game
    with Time.deltaTime which is the time in seconds it took to complete the last frame.

    So you should have something like:
    Code (CSharp):
    1. mainLight.intensity = Mathf.Lerp(1,0,Time.deltaTime * speed);
    ^
    ||
    Did you see that cool "code" tag usage?
     
  3. Pi_User5

    Pi_User5

    Joined:
    Sep 27, 2016
    Posts:
    4
    Unity says speed does not exist in current context. Am I missing something?

    Thanks for the code tag. I tried searching before I posted but I gave up :D.
     
  4. CloudKid

    CloudKid

    Joined:
    Dec 13, 2015
    Posts:
    207
    Yeah, by speed I mean a value that you define to control how fast the fade is animated.
    You have 2 options:

    Code (CSharp):
    1.     //Option A: declare a global speed and set it from inspector
    2.     public float Speed;
    3.  
    4.     void Update()
    5.     {
    6.         if (mainLight.intensity <= 1)
    7.         {
    8. #if DEBUG
    9.             print(mainLight.intensity);
    10. #endif
    11.             mainLight.intensity = Mathf.Lerp(1, 0, Time.deltaTime * Speed);
    12.         }
    13.         if (mainLight.intensity <= 0)
    14.         {
    15. #if DEBUG
    16.             print("Light intensity is 0");
    17. #endif
    18.             //Option B: or just hardcode it directly into your lerp
    19.             mainLight.intensity = Mathf.Lerp(0, 1, Time.deltaTime * 0.5f);
    20.         }
    21.     }
     
  5. Pi_User5

    Pi_User5

    Joined:
    Sep 27, 2016
    Posts:
    4
    Hmm. Neither of the options seemed to work.
     
  6. CloudKid

    CloudKid

    Joined:
    Dec 13, 2015
    Posts:
    207
    yeah my bad, I was tired. Try this:
    Code (CSharp):
    1. mainLight.intensity = Mathf.Lerp(mainLight.intensity, 1, Time.deltaTime * 0.5f);
     
  7. Errorsatz

    Errorsatz

    Joined:
    Aug 8, 2012
    Posts:
    555
    The Lerps are off, even the last one produces a logarithmic effect where it never quite reaches the target. But more importantly -

    The way those conditionals are written won't work.
    Let's say the intensity starts at 1. It will go down to zero, and then ...
    1) The first conditional still runs, putting at zero again.
    2) The second condition runs, putting it at slightly above zero.
    3) Next frame, the first conditional runs and puts it at zero ...
    End result, it would freeze at a tiny bit above totally dark.

    You need an additional state variable for which direction the light is changing. Something like this:
    Code (csharp):
    1. public float speed;
    2. private float direction = 1f;
    3.  
    4. private void Update () {
    5.    mainLight.intensity += Time.deltaTime * speed * direction;  // Lerp not needed
    6.    if(mainLight.intensity >= 1f) {
    7.       direction = -1f;
    8.    }
    9.    else if(mainLight.intensity <= 0f) {
    10.       direction = 1f;
    11.    }
    12. }
    You could technically save a float and flip the sign of speed instead. But that gets screwed up if anything external wants to change the speed, and is less clear.
     
    Last edited: Sep 27, 2016
    Pi_User5 likes this.
  8. CloudKid

    CloudKid

    Joined:
    Dec 13, 2015
    Posts:
    207
    Take my code with the exact solution and don't actually learn anything. Also my version is better.

    Code (CSharp):
    1.  
    2.     public float Speed;
    3.  
    4.     void Start()
    5.     {
    6.         StartCoroutine("AnimateIntensity");
    7.     }
    8.  
    9.     private IEnumerator AnimateIntensity()
    10.     {
    11.         var t = 0f;
    12.         var destination = mainLight.intensity <= 0.5f ? 1 : 0;
    13.         while (t <= 1)
    14.         {
    15.             mainLight.intensity = Mathf.Lerp(mainLight.intensity, destination, t);
    16.             t += Time.deltaTime * Speed;
    17.             yield return null;
    18.         }
    19.  
    20.         StartCoroutine("AnimateIntensity");
    21.     }
     
    Pi_User5 likes this.
  9. Pi_User5

    Pi_User5

    Joined:
    Sep 27, 2016
    Posts:
    4
    Thanks everyone! It works just fine! Thanks!