Music crossfade between Levels Unity 5

Based on various tutorials and code snippets I have seen here is a method to have persistent audio that can be crossfaded between Levels (or Scenes) in Unity 5.

01 First import all your audio –  for this I’m using music, not SFX

Screen Shot 2016-08-11 at 16.43.55
Set up the Audio Source

02 In Scene01 Add an Audio Source for each music track, Assign an Audio clip for each AudioSource and set it to Loop & Play on Awake .

03 Parent all the Audio sources to a Game Object ( and rename it to ‘AudioSources‘)

Screen Shot 2016-08-11 at 16.59.13
Set up game object holding all the Audio Sources

04 Add the Music Manager script to the AudioSources GameObject – this will keep the audio sources alive in between each scene and make sure they are not duplicated on level load.

05 R-click in your Assets Folder and Create/ Audio Mixer

06 Open the Audio Mixer, the Master Mixer is the overall volume.

07 in Groups R-Click Master and make  a child group for each Audio Source – this will give you extra  the equivalent of audio channels. (I have 4 levels and 4 music tracks – 1 piece of music for each level and so I make 4 Child Groups)

08 Back in each Audio Source assign each output to one of your Groups ( – I have kept my naming simple so each Audio Clip, AudioSource, Mixer Group etc. has the same name and I’m numbering them to correspond to the Level number, So MyAudioClip01, I want to play in Level01 and so on.. )

09 Copy the AudioSources game object to each level.

10 Back in the Audio Mixer each group is equivalent to a channel, when the level is playing click the small Edit In  Play Mode button,  slide the volume(s) up & down to crossfade the tracks. Unity remembers settings when you stop playing. You can add other effects to the mixers — I’m not covering that here.

Screen Shot 2016-08-11 at 16.43.49
Audio Mixer groups – really they are like audio channels

11 The next thing to do is to make Snapshots in the Audio Mixer for the volume settings for each music track, for each Level. For example in the image above in MyLevel01 I want the Master volume to be 0 (full volume) and the first track to have it’s volume set to 0 as well. The other tracks are quiet so their volumes are set to -80. So I set this up, then click the + next to Snapshots to make a new snapshot.

In MyLevel02 I want the Master and track 2 to be 0 and the other tracks to be -80 and so on. Set up a snapshot for each Level you have.
12 You can rename and move snapshots up & down the list and set a default snapshot-  my default is one with all volumes set to -80

Screen Shot 2016-08-11 at 16.59.22
Several snapshots set up, each snapshot has its volume (attenuation) level set differently

— The idea is that in code we blend between snapshots over time so that the volume sliders move between positions fading tracks in and out. Because of how the scripts are set up, AudioSources persist in all Levels so crossfading doesn’t get interupted  during level change.

13 The last thing to do is to add another GameObject to each level call it ‘ScriptHolder’  and add a script called SceneGo to it. This script does two things – on a R Mouse click  on Game Window to jumps to whichever Level number you set in  the ‘Scene To Jump To’ field .

Secondly it transitions to whichever Snapshot you have set in the ‘Music to Fade In’ field. The ‘Bpm Fade in Speed’  sets the speed of the audio transition. Lower is slower –  12 is nice.

Screen Shot 2016-08-11 at 17.11.34
Scene Go script in inspector has user configurable settings

14 Note. Make sure each Level is added to the Build settings otherwise it wont work.

15 In the Editor you can play your levels and with the AudioMixer open see & hear the transitions happening.

. . . . . . . .

Music Manager c# script

. . . . . . . .

using UnityEngine;
using System.Collections;

/// <summary>
/// Music manager. Stops a game object with an audio source attached from being destroyed on level load
/// so that the music plays from level to level…This means i may be able to do a crossfade usign the mixer and
/// audio snapshots fat chance!
/// </summary>

public class MusicManager : MonoBehaviour
{
private static MusicManager _instance;

public static MusicManager instance
{
get
{
if(_instance == null)
{
_instance = GameObject.FindObjectOfType<MusicManager>();

//Tell unity not to destroy this object when loading a new scene!
DontDestroyOnLoad(_instance.gameObject);
}

return _instance;
}
}

void Awake()
{
if(_instance == null)
{
//If I am the first instance, make me the Singleton
_instance = this;
DontDestroyOnLoad(this);
}
else
{
//If a Singleton already exists and you find
//another reference in scene, destroy it!
if(this != _instance)
Destroy(this.gameObject);
}
}

public void Play()
{
//Play some audio!
}
}

. . . . . . . . . .

Scene Go c# script adapted from the ‘CombatMusicControl’ script

. . . . . . . . . .

using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
//think i need this
using UnityEngine.Audio;

public class SceneGo : MonoBehaviour {

public int SceneToJumpTo = 1;

//audio transitio stuff
public AudioMixerSnapshot MusicToFadeIn;
//public AudioMixerSnapshot MusicOut;
private float m_TransitionIn;
private float m_TransitionOut;
private float m_QuarterNote;
public float bpmFadeInSpeed = 128;
//end
// more audio Use this for initialization
void Start () {
m_QuarterNote = 60 / bpmFadeInSpeed;
m_TransitionIn = m_QuarterNote;
//m_TransitionOut = m_QuarterNote * 32;

}

void Update() {
if (Input.GetMouseButtonDown (0))
Debug.Log (“Pressed left click.”);

if (Input.GetMouseButtonDown(1))
SceneManager.LoadScene(SceneToJumpTo);
MusicToFadeIn.TransitionTo(m_TransitionIn);
if (Input.GetMouseButtonDown(2))
Debug.Log(“Pressed middle click.”);

}
}

. . . . . . . .