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…
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.
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);
}
}
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?