- Home /
Playing music through complicated scene
i'm having a problem with background music . I have 4 scene ( Test 1, Test 2, Trainning 1, Trainning 2 ) . I created GameObject called : "Test Music" with Tag "Background Music", GameMusic Script, Audio : Test.ogg in Test 1 + 2 scene and "Trainning Music" with the same tag, same Script, Audio : Trainning.ogg in Trainning 1 + 2. So what i want to do is : When changing the scene from Test 1 to Test 2, Trainning 1 to Trainning 2, Test 2 to Trainning 1 and Trainning 1 to Test 2, The script will find object with tag "Background Music" and check : If GameObject in previous scene( Using DontDestroyOnLoad ) have the same name as GameObject in current scene, the script will destroy GameObject in current scene. If they have different name , the script will destroy the GameObject in previous scene. I know i can find a lot of way about how to do it, but it's not what i want to do. For Example : https://answers.unity.com/questions/1253516/playing-audio-through-multiple-scenes.html This answers almost like my purpose but it add scene in order to make the audio to be destroyed when change to some specific scene. But if i have 60 70 scene with different music, do i need to add all of the scene ? or if i set specific scene to play specific music (Like playing Test.ogg when load Test 1 + 2 scene) , can music continue to play when go to Test 2 from Test 1 ?
Answer by Harinezumi · May 15, 2018 at 12:25 PM
Is this what you want?
// this will only be run for the game object in the newly loaded scene
private void Awake () {
GameObject[] backgroundMusics = GameObject.FindGameObjectsWithTag("Background Music");
// note: if there are more than 2 objects found, you might end up without any background music!
for (int i = 0; i < backgroundMusics.Length; ++i) {
if (backgroundMusics[i] != gameObject) { // check that it is not itself
if (backgroundMusics[i].name != name) { Destroy(backgroundMusics[i]); } // destroy background music with different name
else { Destroy(gameObject); } // keep background music with same name
}
}
DontDestroyOnLoad(gameObject);
}
However, instead of this I would do it with a singleton background music object which is told what music to play in each scene. That is, you would have a background music object with the below script in each scene, and at the beginning of each scene call from a different script (a kind of scene initializer) BackgroundMusic.Instance.Play(<track for the scene>);
. The script (might need):
public class BackgroundMusic : MonoBehaviour {
private BackgroundMusic instance = null;
public BackgroundMusic Instance { get { return instance; } }
private AudioSource audioSource;
private AudioClip currentTrack;
private void Awake () {
if (instance == null) {
instance = this;
DontDestroyOnLoad(gameObject);
audioSource = GetComponent<AudioSource>();
}
else if (instance != this) { Destroy(gameObject); }
}
public void PlayTrack (AudioClip track) {
// change track if it is different
if (currentTrack != track) {
currentTrack = track;
// start if changed and not null, stop if it is null
if (audioSource.clip != null) { audioSource.Play(); }
else { audioSource.Stop(); }
}
}
}