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.
Oh, okay. I think i was missing something. So i am supposed to create a NEW object in every scene, tag it with "Music" and then attach the script to it, and in the scenes that i don't want it to play, i put the "stop" script in any object that i want? I made a single object with the music tag in the main menu. That's what i was missing i think. Also, i don't want to bother you, but the "GameObject.FindGameObjectWithTag("Music").GetComponent().PlayMusic();" isn't working. [80730-error.png|80730]
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?
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.
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: https://docs.unity3d.com/ScriptReference/GameObject.html
A Simpler way would be to set the GameObject with the audio souce to DontDestroy snd then in its Update check the scene its in and destroy if its the scene you dont want…
void Start()
{
if (SceneManager.GetActiveScene().name != “Racing”) {
DontDestroyOnLoad(gameObject);
}
}
// Update is called once per frame
void Update()
{
if (SceneManager.GetActiveScene().name == "Racing") {
Destroy(gameObject);
}
}
This approach would work if your audio manager is not present in subsequent scenes. But if you return (or enter) a scene with a duplicate this behaviour will keep the duplicate as well. The reason for the slightly more complex approach is to avoid this problem. My use case had this problem since I was returning to the MainMenu scene multiple times - each time causing a duplicate to be created that was not destroyed. Adding the duplicate check OnSceneLoaded was the solution.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Audio;
public class Misc : MonoBehaviour
{
private void Awake()
{
Misc[] objects = FindObjectsOfType<Misc>();
if (objects.Length > 1)
{
Destroy(objects[1].gameObject);
return;
}
DontDestroyOnLoad(gameObject);
}
}
I have a little of a different problem: I have three audio tracks playing at the same time (one drums, one melody and one some other rythm instruments) so that I can vary the music by changing their volumes separately.
The audio sources continue playing at the scene load, but they get out of sync. As a result the music is totally messed up. Any idea how I can keep them in sync? Short of stopping and restarting?
I'm also interested in it. I would like to get some more details about it. I hope someone will help.
– MarkTailorI would like to know how to fix this also.
– datnasty2_0