- Home /
Make music continue playing through scenes
Hi! I have an audio source attached to an object in my main menu scene, and i wanted it's music to keep playing even when you are in SOME other scenes. For an example:
The main song is playing. The player is in the Main Menu scene and the music is at 1:43. The player clicks on Select Map and goes to the Map Selection scene. Then, the music continues from 1:43 until it finishes. As it has the loop, it plays again and again.
I don't want the song to play in all the scenes, just some specific. Do someone know how to do this? I don't have any idea of how to make this...
I'm also interested in it. I would like to get some more details about it. I hope someone will help.
Answer by Denvery · Oct 21, 2016 at 09:06 PM
Let's try this.
Create GameObject and assign any custom tag. For example, create tag "Music" and assign. Attach script to this game object and make DontDestroyOnLoad:
using UnityEngine;
public class MusicClass : MonoBehaviour
{
private AudioSource _audioSource;
private void Awake()
{
DontDestroyOnLoad(transform.gameObject);
_audioSource = GetComponent<AudioSource>();
}
public void PlayMusic()
{
if (_audioSource.isPlaying) return;
_audioSource.Play();
}
public void StopMusic()
{
_audioSource.Stop();
}
}
Attach your audio source to this object.
From scenes, where you want to play music, call method:
GameObject.FindGameObjectWithTag("Music").GetComponent<MusicClass>().PlayMusic();
From scenes, where you don't want to play music, call method:
GameObject.FindGameObjectWithTag("Music").GetComponent<MusicClass>().StopMusic();
This worked for me, but when I went back to one of the scenes, it played the music again over the first time it played, and this happened whenever I went into that menu. And I doing something wrong?
I have no idea how to call the method. Im still very new too unity and coding as a whole and I am very confused.
Thank you So $$anonymous$$uch its working very well.
this doesn't work with the audio source with the loop true though
I would change it to this, because this way if you go back to the scene where the music object was placed it won't make another music object.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Music : MonoBehaviour
{
private AudioSource _audioSource;
private GameObject[] other;
private bool NotFirst = false;
private void Awake()
{
other = GameObject.FindGameObjectsWithTag("Music");
foreach (GameObject oneOther in other)
{
if (oneOther.scene.buildIndex == -1)
{
NotFirst = true;
}
}
if (NotFirst == true)
{
Destroy(gameObject);
}
DontDestroyOnLoad(transform.gameObject);
_audioSource = GetComponent<AudioSource>();
}
public void PlayMusic()
{
if (_audioSource.isPlaying) return;
_audioSource.Play();
}
public void StopMusic()
{
_audioSource.Stop();
}
}
Hello, I have tried using your codes but every time I go back to the scene where I created the base game object, the game object multiplies.
Thanks you
Answer by elvirais · Oct 23, 2016 at 09:18 PM
This works for me, latest version of unity: (C# code) (I also found this code somewhere on this forum :)
using UnityEngine;
using System.Collections;
public class GameMusicPlayer : MonoBehaviour
{
private static GameMusicPlayer instance = null;
public static GameMusicPlayer 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
}
This code works for me as well, however, how to I stop the music from playing when entering a scene where I don't want the music to play?
To stop the music in the new scene, you'll need a link to the gameobject. Since it comes over from another scene, I used a GameObject.Find or .FindWithTag function to get the object:
Answer by keszeial · Jan 24, 2021 at 03:42 PM
First thread I found when looking for a solution to this problem, so I'll add to this thread.
Here is a working solution that avoids the use of singletons, allowing you to add the script to multiple objects in the scene and tweak the behaviour via the inspector:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// Attach this component to objects that you want to keep alive (e.g. theme songs) in certain scene transitions.
/// For reusability, this component uses the scene names as strings to decide whether it survives or not after a scene is loaded
/// </summary>
public class DontDestroyOnSelectedScenes : MonoBehaviour
{
[Tooltip("Names of the scenes this object should stay alive in when transitioning into")]
public List<string> sceneNames;
[Tooltip("A unique string identifier for this object, must be shared across scenes to work correctly")]
public string instanceName;
// for singleton-like behaviour: we need the first object created to check for other objects and delete them in the scene during a transition
// since Awake() callback preceded OnSceneLoaded(), place initialization code in Start()
private void Start()
{
DontDestroyOnLoad(this.gameObject);
// subscribe to the scene load callback
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
// delete any potential duplicates that might be in the scene already, keeping only this one
CheckForDuplicateInstances();
// check if this object should be deleted based on the input scene names given
CheckIfSceneInList();
}
void CheckForDuplicateInstances()
{
// cache all objects containing this component
DontDestroyOnSelectedScenes[] collection = FindObjectsOfType<DontDestroyOnSelectedScenes>();
// iterate through the objects with this component, deleting those with matching identifiers
foreach (DontDestroyOnSelectedScenes obj in collection)
{
if(obj != this) // avoid deleting the object running this check
{
if (obj.instanceName == instanceName)
{
Debug.Log("Duplicate object in loaded scene, deleting now...");
DestroyImmediate(obj.gameObject);
}
}
}
}
void CheckIfSceneInList()
{
// check what scene we are in and compare it to the list of strings
string currentScene = SceneManager.GetActiveScene().name;
if (sceneNames.Contains(currentScene))
{
// keep the object alive
}
else
{
// unsubscribe to the scene load callback
SceneManager.sceneLoaded -= OnSceneLoaded;
DestroyImmediate(this.gameObject);
}
}
}
Just add this script as if it were a component to the parent object (e.g. in the image, the empty game object carrying all the audio sources: "Audio") and write down the name of the scenes it should survive in, then give it a unique string identifier relative to all other scripts in the scene using this component.
This actually worked! I've been looking for the right script for a long time! Thank you man :)
Answer by hexagonius · Oct 21, 2016 at 09:06 PM
Have a look at this post:
http://answers.unity3d.com/questions/11314/audio-or-music-to-continue-playing-between-scene-c.html
Answer by nathanthesnooper · Oct 23, 2016 at 11:15 PM
This should work. Remember you can always save the Time Elapsed in a PlayerPrefs alternatively.
void Start () {
DontDestroyOnLoad(this.gameObject);
}
Not tested yet but should work.
Your answer
Follow this Question
Related Questions
make music continue play across scenes except one scenes 1 Answer
Can not play a disabled audio source persistent problem 0 Answers
Play Animation if Sound Output 0 Answers
Sound Timing 1 Answer
Cant repeat Sound 1 Answer