Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How To --> Fade Out Music Before Loading Level

Discussion in 'Scripting' started by trevorchandler, Jul 17, 2009.

  1. trevorchandler

    trevorchandler

    Joined:
    May 16, 2009
    Posts:
    121
    Hello all,

    This is some simple code I wrote, but perhaps it may be of use to someone,

    I use this to fade out my level music before I load a new level,

    The new level is loaded by a button press, the button code is also below.
    The level that gets loaded is set on the game object by the 'level' variable.

    Code (csharp):
    1. var level : int;
    2.  
    3. function Update () {
    4. }
    5.  
    6. function OnGUI () {
    7.  
    8.     if (GUI.Button(Rect (168,116,166,28), "")) {    
    9.     FadeOutSoundAndLoadLevel(level);
    10.   }  
    11. }  
    12.  
    13.  
    14. function FadeOutSoundAndLoadLevel (loadLevel : int) {
    15.    
    16. var i : int;
    17.  
    18.     for (i = 9; i > 0; i--)
    19.     {
    20.         audio.volume = i * .1;
    21.         yield new WaitForSeconds (.5);
    22.     }      
    23.     Application.LoadLevel(loadLevel);
    24. }  

    I hope this is of help to someone, you could also fade in by changing this line

    Code (csharp):
    1. for (i = 0; i < 0; i++)
    Farewell,

    Trevor
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    That's going in .5 second steps, though, which could be smoother. (Also a trivial thing: you don't need the "new" keyword in Javascript when doing yield WaitForSeconds.) Here's an audio fade function that I use:

    Code (csharp):
    1. enum Fade {In, Out}
    2. var fadeTime = 4.0;
    3.  
    4. function Start () {
    5.     FadeAudio(fadeTime, Fade.Out);
    6. }
    7.  
    8. function FadeAudio (timer : float, fadeType : Fade) {
    9.     var start = fadeType == Fade.In? 0.0 : 1.0;
    10.     var end = fadeType == Fade.In? 1.0 : 0.0;
    11.     var i = 0.0;
    12.     var step = 1.0/timer;
    13.  
    14.     while (i <= 1.0) {
    15.         i += step * Time.deltaTime;
    16.         audio.volume = Mathf.Lerp(start, end, i);
    17.         yield;
    18.     }
    19. }
    So you call FadeAudio with the number of seconds you want the fade to occur over, plus Fade.In or Fade.Out for the obvious effect.

    --Eric
     
    fidelsoto likes this.
  3. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
  4. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,290
    Hm, for some reason I never do fadings (audio or graphics) this way. I always stuff the update into the Update() or FixedUpdate() function and decrement a value, i.e.:

    Works every time.
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yes, but then you have the Update function running all the time whether you're fading or not, not to mention the added complexity and inflexibility. Using a coroutine also "works every time" but is more efficient and easier to deal with. ;)

    Regarding the linear fading, normally I would agree, but when you're just fading a music track out over a few seconds, it hardly matters.

    --Eric
     
  6. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    True that. Might as well skip the complexity and slowdown of extra code and a power function if you just need to get the sound to go away without making a click sound, which happens when you just use the Stop() function. As it is, it's too much of a pain to design fade-out curves. I thought about making a graphical editor for that, but I'm going to wait and see what Unity 3.0 brings before I waste my time.
     
  7. Accession

    Accession

    Joined:
    Jan 29, 2011
    Posts:
    3
    I know this is an old post, but I found it, so someone else might find this useful. I needed this converted to C# and found it difficult because C# handles the yield very differently. So here's the working code for C Sharp:

    Code (csharp):
    1. enum Fade {In, Out};
    2. float fadeTime = 4.0F;
    3.  
    4. void Start () {
    5.     StartCoroutine(FadeAudio(fadeTime, Fade.Out));
    6. }
    7.  
    8. IEnumerator FadeAudio (float timer, Fade fadeType) {
    9.     float start = fadeType == Fade.In? 0.0F : 1.0F;
    10.     float end = fadeType == Fade.In? 1.0F : 0.0F;
    11.     float i = 0.0F;
    12.     float step = 1.0F/timer;
    13.  
    14.     while (i <= 1.0F) {
    15.         i += step * Time.deltaTime;
    16.         audio.volume = Mathf.Lerp(start, end, i);
    17.         yield return new WaitForSeconds(step * Time.deltaTime);
    18.     }
    19. }
    Note specifically that at the time the function is called, you must explicitly use StartCoroutine.
     
    Last edited: Feb 3, 2011
  8. HenriKay

    HenriKay

    Joined:
    Oct 2, 2010
    Posts:
    6
    Great stuff, Eric! Really helped me out. Thank you.
     
  9. Rispat-Momit

    Rispat-Momit

    Joined:
    Feb 14, 2013
    Posts:
    265
    Hi!

    Thanks for the script Eric!

    I changed it a bit, in order to make it more easy to control the fade in-out function, through the inspector.

    Code (csharp):
    1. var FadeIn : boolean = true;
    2. var FadeOut : boolean = false;
    3.  
    4.  
    5. enum Fade {In, Out}
    6. var fadeTime: float;
    7.  
    8.  
    9. function Start () {
    10. if (!FadeIn)
    11.    
    12.     FadeAudio(fadeTime, Fade.In);
    13. }
    14.  
    15. function FadeAudio (timer : float, fadeType : Fade) {
    16.  
    17.     var start = fadeType == Fade.In? 1.0 : 0.0;
    18.  
    19.     var end = fadeType == Fade.In? 0.0 : 1.0;
    20.  
    21.     var i = 0.0;
    22.  
    23.     var step = 1.0/timer;
    24.    
    25.     while (i <= 1.0) {
    26.  
    27.         i += step * Time.deltaTime;
    28.  
    29.         audio.volume = Mathf.Lerp(start, end, i);
    30.     yield;
    31.  }
    32. }
    33.  
    34. function Update () {
    35. if (!FadeOut)
    36.    
    37.     FadeAudio(fadeTime, Fade.Out);
    38. }
    39.  
    40. function FadeAudio2 (timer : float, fadeType : Fade) {
    41.  
    42.     var start = fadeType == Fade.In? 0.0 : 1.0;
    43.  
    44.     var end = fadeType == Fade.In? 1.0 : 0.0;
    45.  
    46.     var i = 0.0;
    47.  
    48.     var step = 1.0/timer;
    49.    
    50.     while (i <= 1.0) {
    51.  
    52.         i += step * Time.deltaTime;
    53.  
    54.         audio.volume = Mathf.Lerp(start, end, i);
    55.     yield;
    56.  }
    57. }
     
  10. JDuaneJ

    JDuaneJ

    Joined:
    Jul 26, 2014
    Posts:
    29
    Getting parsing errors when I add this code to my game. How is this applied?
     
  11. laurelhach

    laurelhach

    Joined:
    Dec 1, 2013
    Posts:
    229
    what is your error?
     
  12. Dbaxter04

    Dbaxter04

    Joined:
    Aug 14, 2015
    Posts:
    5
    My audio is glitching whenever I use this, any idea why?

     
  13. Dbaxter04

    Dbaxter04

    Joined:
    Aug 14, 2015
    Posts:
    5
    I got this working with a fade in, but I get an initial pop in the audio before the fade starts, any thoughts?

    Thanks

     
  14. AvantBard

    AvantBard

    Joined:
    Dec 7, 2014
    Posts:
    1
    My guess is that the code assumes that your volume is full, or at zero before fading:

    Code (CSharp):
    1.     float start = fadeType == Fade.In? 0.0F : 1.0F;
    2.  
    This will create a 'pop' if your volume is instead set to a lower value, or higher value.

    To fix this you should ensure that your AudioSource's volume is at 1.0f, or 0.0f before fading, or you can change the above code to instead say:

    Code (CSharp):
    1.     float start = audio.volume
    I would also supplement this by stopping other fade coroutines before fading so you don't have odd behavior from two coroutines updating the same value.
     
  15. The-Little-Guy

    The-Little-Guy

    Joined:
    Aug 1, 2012
    Posts:
    297
    You could do it with a basic Lerp

    Code (csharp):
    1. public class FadeOutAudio : MonoBehaviour {
    2.  
    3.     [TooltipAttribute("The audio source")]
    4.     public AudioSource audioSource;
    5.     [TooltipAttribute("Time in seconds to fade out")]
    6.     public float fadeSpeed = 5f;
    7.     [TooltipAttribute("Toggle the fade")]
    8.     public bool startFade = false;
    9.  
    10.     float time = 0f;
    11.  
    12.     void Update(){
    13.         if(startFade){
    14.             audioSource.volume = Mathf.Lerp(1f, 0f, time);
    15.             time += Time.deltaTime / fadeSpeed;
    16.         }
    17.     }
    18.  
    19. }
    20.  
     
  16. krousty_bat

    krousty_bat

    Joined:
    Oct 9, 2012
    Posts:
    60
    Thx for your update,
    This is your same code with the minor changes needed, to make it work on in Unity 5.++

    Code (CSharp):
    1. public class PoisonBeams : MonoBehaviour {
    2.  
    3.     enum Fade {In, Out};
    4.     float fadeTime = 4.0F;
    5.  
    6.     void Start () {
    7.         StartCoroutine(FadeAudio(fadeTime, Fade.Out));
    8.     }
    9.  
    10.     IEnumerator FadeAudio (float timer, Fade fadeType) {
    11.         float start = fadeType == Fade.In? 0.0F : 1.0F;
    12.         float end = fadeType == Fade.In? 1.0F : 0.0F;
    13.         float i = 0.0F;
    14.         float step = 1.0F/timer;
    15.  
    16.         while (i <= 1.0F) {
    17.             i += step * Time.deltaTime;
    18.             GetComponent<AudioSource>().volume = Mathf.Lerp(start, end, i);
    19.             yield return new WaitForSeconds(step * Time.deltaTime);
    20.         }
    21.     }
    22. }
    Once again, thx very much about this!!!
    Simple, and working immediately :).
     
  17. staraffinity

    staraffinity

    Joined:
    Sep 16, 2014
    Posts:
    7
    I'd like to use this script to fade audio out when a button is being clicked. I've tried to add the script as a ”On Click ()” on a button to trigger the fade with the button is pressed. But how to associate it with my audio source?