Fade out and fade in Lights

Hello!
I’m struggling to find a way to make a smooth fade to black transition in order to change scene in VR, so I was thinking to fade all the lights in my scene to black, change scene, and then fade them back in the new scene.

All my lights have different intensity and all of them should have an equal fade time. Do you have any suggestion?

Thank you in advance!

You use lerp or linear interpolation for such things.
You could make a script to which all the lights would subscribe on Awake, or something similar, and then once you decide to lerp the lights, you do the following:

  • store the current intensity (per light)
  • determine the animation duration
  • determine the final intensity
    then
  • each frame, decrease the duration by Time.deltaTime
  • compute the actual interpolation value based on this
  • compute new intensity and set it (per light)

This is merely an example, never tested

using UnityEngine;

public class LightIntensityFader : MonoBehaviour {
 
  [SerializeField] [Range(0.01f, 5f)] float fadeDuration = 1f; // in seconds
  Light[] _lights; // all light objects in the scene
  float[] _saved; // here we save all intensities
  bool _fadingDown = true; // whether we are fading down to black, or back up
  bool _animated = false; // whether this is currently animating the lights
  float _animTime; // how much time is left until animation is done

  void OnEnable() {
    _animated = true;
    _animTime = fadeDuration;
  }

  void Awake() {
    enabled = false;

    _lights = FindObjectsOfType<Light>();
    _saved = new float[_lights.Length];

    for(int i = 0; i < _lights.Length; i++)
      _saved[i] = _lights[i].intensity;
  }

  void Update() {
    if(!_animated) return;

    _animTime -= Time.deltaTime;

    if(_animTime < 0f) {
      _animTime = 0f;
      _animated = false;
      //_fadingDown = !_fadingDown; // this got moved down
      enabled = false;
    }

    var t = _animTime / fadeDuration;
    if(_fadingDown) t = 1f - t;

    for(int i = 0; i < _lights.Length; i++)
      _lights[i].intensity = Mathf.Lerp(0f, _saved[i], t);

    if(!_animated) _fadingDown = !_fadingDown;
  }

}

Now, add this to any object on the scene, and you should be able to simply flick the switch on the component itself (in play time), and it will animate for as long as you have set duration. Once it’s finished it will disable itself, and when you flick it again, it will again animate back to the original values.

It might contain errors or bugs, I’m sorry in advance if that’s the case, but the key concepts are there.
Pay special attention to var t = _animTime / fadeDuration this is literally the percentage of where we’re at currently, in abstract terms, simply considering how much it should last, and how much time has elapsed. And then _lights.intensity = Mathf.Lerp(0f, _saved*, t); with which we basically interpolate between 0 and the original value based on this percentage.*
The line that says if(_fadingDown) t = 1f - t; simply inverts the percentage, and this is how you can fade both up and down. Hopefully it works so you can test this for yourself.
edit: fixed some typos in code.
edit2: fixed a bug.

Thank you for the help!
I tried the script and it works, but unfortunately once the light intensity falls to 0, the script doesn’t disable by itself and continues to fade in and out… I’m trying to understand why

I got some things wrong, make the following change
delete the line that says _fadingDown = !_fadingDown (35)
Add the following line to the end of Update (on line 44)

if(!_animated) _fadingDown = !_fadingDown;

the switch was too soon, and the t value was wrong.

Regarding enabling, I’m not sure if you’ve diagnosed it correctly, I’ve tried it and it works.
Except that bug of course.

consider refactoring this for your convenience. fading in/out do not need to be chained for instance; it can be made to trigger programmatically; _animated variable is actually redundant, and so on… ask if you need further help to customize this for a particular scenario.

sorry to resurrect this old thread, but i’m curious if someone could show me how to apply this script to only a single light? this simple example doesn’t look as smooth and goes back and forth indefinitely

public class example : MonoBehaviour
{
    Light myLight;

    void Start()
    {
        myLight = GetComponent<Light>();
    }

    void Update()
    {
        myLight.intensity = Mathf.PingPong(Time.time, 8);
    }
}

The script you have here should apply only to the light the script is attached to, so I’m not sure what you mean by “how to apply this script to only a single light”.

Also, please describe what you want to do exactly.

sorry if i’m not communicating very well! i meant to ask how the script above ( Fade out and fade in Lights ) could be applied to a single light. thank you for any help

The easiest way would be to remove the line : _lights = FindObjectsOfType();

and add [SerializeField] in front of Light[ ] _lights.

Then drag the one light you want to fade into the array in the inspector.

The script you posted by its design is intended to:

  • handle ONE light only
  • be placed on the GameObject containing that light
  • to run indefinitely

If you just need to change a light over time, make an animation and be done with it, no need to code.

Fading, simple and easy:

Otherwise…

Please don’t necro-post. As you can see, your problem is already completely different from the original thread, leading to chaos, confusion and concern by everybody who is now getting pinged by these notices that you replied to their thread.

If you have a new question, make a new post. It’s FREE!!

How to report your problem productively in the Unity3D forums:

http://plbm.com/?p=220

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, log output, variable values, and especially any errors you see
  • links to actual Unity3D documentation you used to cross-check your work (CRITICAL!!!)

The purpose of YOU providing links is to make our job easier, while simultaneously showing us that you actually put effort into the process. If you haven’t put effort into finding the documentation, why should we bother putting effort into replying?

If you post a code snippet, ALWAYS USE CODE TAGS:

How to use code tags: Using code tags properly

  • Do not TALK about code without posting it.
  • Do NOT post unformatted code.
  • Do NOT retype code. Use copy/paste properly using code tags.
  • Do NOT post screenshots of code.
  • Do NOT post photographs of code.
  • Do NOT attach entire scripts to your post.
  • ONLY post the relevant code, and then refer to it in your discussion.