Audio or Music to continue playing between scene changes

Is there a simple way to have audio like a background music track to carry over to another scene without stopping or restarting?

I've found a script similar but it was more like a jukebox and it was in C#, I'm still baby-stepping through Javascript.

What you'd probably do is attach the AudioClip to a game object to which you also have attached a script which calls DontDestroyOnLoad. That way, the game object does not get destroyed when the new scene is loaded and audio should keep playing.

EDIT: Of course, if you have that game object in every scene, it will duplicate the sound. One solution to that is following what I call the "Unity Singleton" pattern which is kind of like the classic Singleton pattern but specific to Unity (this is C# because I find examples easier to understand in C# - UnityScript follows right below):

public class MyUnitySingleton : MonoBehaviour {

    private static MyUnitySingleton instance = null;
    public static MyUnitySingleton Instance {
        get { return instance; }
    }
    void Awake() {
        if (instance != null && instance != this) {
            Destroy(this.gameObject);
            return;
        } else {
            instance = this;
        }
        DontDestroyOnLoad(this.gameObject);
    }

    // any other methods you need
}

What this basically does is: Check for an existing instance, if there already is an instances, destroy self - if not, store this is instance (so anyone who's coming later will destroy themselves). This also provides a public accessor so you can access the single instance from anywhere via MyUnitySingleton.Instance. Of course, you'd have your sound-specific methods also in that same class/script.

So here's (hopefully) the same in UnityScript (note that this must be in a file called "MyUnitySingleton" - or, in other words: replace any occurrence of "MyUnitySingleton" with the filename of your script):

private static var instance:MyUnitySingleton;
public static function GetInstance() : MyUnitySingleton {
return instance;
}

function Awake() {
    if (instance != null && instance != this) {
        Destroy(this.gameObject);
        return;
    } else {
        instance = this;
    }
    DontDestroyOnLoad(this.gameObject);
}

Ok, I've eventually answered my own question. For great justice, I'll post my findings for others to see/nab/yank/freeb. The code is simple to use, and extremely handy.

First, on your title screen or whatever is your first scene, add this script to a game object with an audio source. Name this game object "Game Music".

private static var instance:MyUnitySingleton;
public static function GetInstance() : MyUnitySingleton {
return instance;
}

function Awake() {
    if (instance != null && instance != this) {
        Destroy(this.gameObject);
        return;
    } else {
        instance = this;
    }
    DontDestroyOnLoad(this.gameObject);
}

(That bit of code was kindly provided by Jashan, thank you Jashan.) Create a new empty game object and add a "Music Manager" script to it.

Var NewMusic: AudioClip; //Pick an audio track to play.

function Awake ()
     {
          var go = GameObject.Find("Game Music"); //Finds the game object called Game Music, if it goes by a different name, change this.
          go.audio.clip = NewMusic; //Replaces the old audio with the new one set in the inspector.
          go.audio.Play(); //Plays the audio.
     }

Have this Music Manager in your scenes. If it is different, it will change the music. If it is the same, it will keep playing and won't be interrupted by level loads or anything. To stop the music, use the Music Manager and select None for the audio. Alternatively, you can always tell the Game Music object to stop its audio to and all those commands that go with it. I suggest never really destroying it, this one object can set the music for your entire game.

I hope you like it.

I looked around for solutions, but none went out to do exactly what we really wanted.
Consider you have only one object that can play the music and there will be no copies of it on the other scenes. Activate the Play On Awake and Loop check boxes.
Here’s my solution in simple JavaScript and I hope this is what you might be looking for.

So, consider you have an object called Jukebox with an AudioSource component in it.
It’s quite simple, all you need to do is keep track of the current time. Check this:

var currentMusicTime:float;

function Start(){
   DontDestroyOnLoad(gameObject);
}

function Update(){
   currentMusicTime=audio.time;
}

function OnLevelWasLoaded(lvl:int){
   audio.time=currentMusicTime;
}

I’ll post this on other similar threads, I hope it’s ok to do so and I hope it helps!

This is what I have so far, it doesn't seem to work. Instead of comparing audio tracks, it compares names. The surviving gameobject gets renamed to differentiate between the new music manager to the old one.

private static var instance:MusicManager;

public static function GetInstance() : MusicManager 
   {
      return instance;
   }

function Awake() 
   {
      if (instance != null && instance != this) 
         {
            Destroy(this.gameObject);
            return;
         } 

      else 
         {
            instance = this;
            var GameMusic : GameObject = GameObject.Find("GameMusic");
            var OldGameMusic : GameObject = GameObject.Find("OldGameMusic");

            If (GameMusic) 
               {    		
                  Destroy(OldGameMusic);
               }
         }

      this.gameObject.name = "OldGameMusic";
      DontDestroyOnLoad(this.gameObject);
   }

@script RequireComponent(AudioSource)

Rimrook left out a vital piece of the continuing music puzzle, an if statement. I believe the second set of code should look like this:

var NewMusic: AudioClip; //Pick an audio track to play.

function Awake () {
     var go = GameObject.Find("Game Music"); //Finds the game object called Game Music.
     if (go.audio.clip != NewMusic) { 
         go.audio.clip = NewMusic; //Replaces the old audio with the new one set in the inspector.
         go.audio.Play(); //Plays the audio.
     }
}

Rimrook’s solution worked as a baseline in one of our new titles. Thank you RimRook!

However, I noticed that if you are using Audio Sources with “Play On Awake” the music may start in the new scene before it can be associated with the singleton and removed, creating a brief two-song at once audio glitch.

So I turned off Play on Awake on all background music sources, then updated the code to start playing in the Awake loop only if no other music is playing, or if the clip is different. Also, if the volume is different on the new scene audio source, this has a potential to create issues if an audio clip switch is needed, so my code handles that as well:

using UnityEngine;
using System.Collections;

public class MusicSingleton : MonoBehaviour {
    
	private static MusicSingleton instance = null;

	public static MusicSingleton Instance {
		     get { return instance; }
	}

	void Awake() 
	{
		if (instance != null && instance != this) 
		{
			audio.Stop();
			if(instance.audio.clip != audio.clip)
			{
				instance.audio.clip = audio.clip;
				instance.audio.volume = audio.volume;
				instance.audio.Play();
			}

			Destroy(this.gameObject);
	        return;
		} 
		instance = this;
		audio.Play ();
		DontDestroyOnLoad(this.gameObject);
	}
}

This one works well for me, you have to add an audio source component to an empty game object and add the music to that component. Oh! and you gotta “uncheck” the “play on awake”

static var AudioBegin	: boolean = false;
     
function Awake()
{
	if (!AudioBegin)
	{
		audio.Play();
		DontDestroyOnLoad(gameObject);
		AudioBegin = true;
	}
}

i followed the code and it works perfectly fine, but my question is as i couldnt understand the code and thus cant manipulate, what would i need to do to stop the game theme music for example wen the user reaches the main game playing level there needs to start a new music so at that particular game level id want that the main game music shall stop playing and this new music starts at the game level. i followed what rimrock suggested, the code of game music and music manager and it works fine, but my concern is that wen id built the game level and at that instance would want the main game music to stop playing and this new music plays in that game level only then what manipulations i would have to make to the code suggested by Rimrock of the game music and music manager script.

@Rimrook : i tried your script…i applied one script in main scene
and second script(music manager scene) in all other scenes…it works fine in 4 scenes but it is not working in rest of the scenes…

i have applied audio source in main scene only…haven’t applied it on rest of all the scenes.
following is the first script.

private static var instance : musicscript;
public static function GetInstance() : musicscript {
return instance;
}
 
function Awake() {
    if (instance != null && instance != this) {
        Destroy(this.gameObject);
        return;
    } else {
        instance = this;
    }
    DontDestroyOnLoad(this.gameObject);
}

here is the second script…

var NewMusic: AudioClip; //Pick an audio track to play.
 
function Awake ()
     {
          var go = GameObject.Find("Game Music"); //Finds the game object called Game Music, if it goes by a different name, change this.
          go.audio.clip = NewMusic; //Replaces the old audio with the new one set in the inspector.
          go.audio.Play(); //Plays the audio.
     }

please help…

@stealth_3x That is the right solution! I had a problem when I returned the to base level that the music (because of awake in the inspector) tried to start up for just a second all over again. Your script fixed it! Thanks a bunch! :wink: (I wrote in C# though)

Hi I tested the @Rimrook and works but have 2 problems:

-If I turn back to the main scene the sound restarts.

-If I use a different sound in a scene and that scene is restarted, the sound it restarts too.

Someone can help? thanks :smiley:

None of the answers work or are understandable. None of them seem to even give complete info

I searched the answers and I made my own one as the simplest way. Firstly thank you for DontDestroyOnLoad(); function because I only used that.

Now You have to create a gameobject that manage the levelloading.
and than add this script.
public AudioSource voice;

public void LoadLevel(string name) {
    Application.LoadLevel(name);
    DontDestroyOnLoad(voice);
}

Select your audio from unity and its finished.

Hi everybody!!! My name is Ben Shaw, and after a loooooong time of trying to solve this problem I think I might have come up with a solution!!! Some of those other answers just didn’t work so I tried using playerprefs to write the changes to disk. It worked out really well!!! All you have to do is put this script on whatever GameObject plays music, and make that GameObject a Prefab. put that prefab in every scene you want, and it should work seamlessly! There are soooo many other ways to do this, but mine makes some sense to me, so I thought id share it with all of you!
Also, Im only 15 years old so IM NOT THE BRIGHTEST! If you can add on to my solution it would be greatly appreciated!

Also, the way Im thinking of getting the music to restart on every launch of the game is to make a separate scene that quickly resets the player pref and changes to the menu scene. That way itll only be called one time per launch, as the menu scene gets visited quite a lot.

public class MusicThroughScenes : MonoBehaviour
{
    private float CurrentMusicTime;
    private AudioSource audioSource;

    private void Awake()
    {
        audioSource = gameObject.GetComponent<AudioSource>();
        CurrentMusicTime = PlayerPrefs.GetFloat("MusicTime", 0);
        audioSource.time = CurrentMusicTime;
    }

    private void Update()
    {
        CurrentMusicTime = audioSource.time;
        PlayerPrefs.SetFloat("MusicTime", CurrentMusicTime);
    }
}

Add multiple tracks, All flows seamlessly. Enjoy.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{

AudioSource myAudioSource;
[SerializeField] AudioClip[] musicTracks;
int count;
int m1;

private void Awake()
{
    
    int gameMusicCount = FindObjectsOfType<TestScript>().Length;
    if (gameMusicCount > 1)
    {
        gameObject.SetActive(false);
        Destroy(gameObject);
    }
    else
    {
        DontDestroyOnLoad(gameObject);
    }


}

public void Start()
{
    
    myAudioSource = GetComponent<AudioSource>();
    
    AudioClip clip = musicTracks[(m1)];
    myAudioSource.PlayOneShot(clip);
    count = 1;
    m1 = 0;

}
    public void Update ()
    
    {
    

    if (!myAudioSource.isPlaying)
    {
        
        AudioClip clip =  musicTracks[(count++)];
        myAudioSource.PlayOneShot (clip);
    
    }

    if (count >= musicTracks.Length)
    {
        count = 0;
        
    }

}
public void ResetGame()
{
    Destroy(gameObject);
}

    
}

Probably just an easy way of doing it:

void Awake()
{
GameObject music = GameObject.FindGameObjectsWithTag(“music”);
if (music.Length > 1)
{
Destroy(this.gameObject);
}
DontDestroyOnLoad(this.gameObject);
this.gameObject.SetActive(true);
}

I did mine a little differently. I first created an empty game object and dropped my audio source onto it. I then created a new script called GameMusic

Here’s the code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameMusic : MonoBehaviour
{
    void Awake()
    {
        SetUpSingleton();
    }

    private void SetUpSingleton()
    {
        if (FindObjectsOfType(GetType()).Length>1)
        {
            Destroy(gameObject);

        }
        else
        {
            DontDestroyOnLoad(gameObject);
        }
    }

}