I wanted to have the music be the same for the end screen and main menu and continue that music if you click “Main Menu” on the end screen, but have different music for the game itself. After reading a previous post where someone wanted to do this too, I came up with a slightly different method than what they did. The previous poster was not wrong in their methods, and I’m not saying I’m more right. This is just my method.
Rather than have two different audio source gameobjects, I instead created 3 new serialized fields, two for the music tracks, and one for the audio source.
The audio player will then stop the music, load the appropriate clip, and then play it.
I then used the Singleton method to store a variable for the previous scene’s index and, in my “PlayMenuMusic” method I added a conditional that will only stop and start the music again if the previous scene index was not 2 (the index for my end screen). I’m not sure if there’s a way to keep that particular variable dynamic should I add more scenes, but this works for such a small project.
Code Below
Level Manager Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelManager : MonoBehaviour
{
static LevelManager instance;
AudioPlayer audioPlayer;
[SerializeField] float sceneLoadDelay = 2f;
[SerializeField] int prevScene;
void OnEnable() {
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void Awake() {
ManageSingleton();
audioPlayer = FindObjectOfType<AudioPlayer>();
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode){
if(scene.name == "MainMenu" || scene.name == "EndScreen"){
AudioPlayer.PlayMenuMusic(prevScene);
}else if(scene.name == "Game"){
AudioPlayer.PlayGameMusic();
}
prevScene = scene.buildIndex;
}
void ManageSingleton(){
if(instance != null){
gameObject.SetActive(false);
Destroy(gameObject);
}else{
instance = this;
DontDestroyOnLoad(gameObject);
}
}
public void LoadGame(){
SceneManager.LoadScene("Game");
}
public void LoadMainMenu(){
SceneManager.LoadScene("MainMenu");
}
public void LoadEndScreen(){
StartCoroutine(WaitAndLoad("EndScreen", sceneLoadDelay));
}
public void QuitGame(){
Application.Quit();
}
IEnumerator WaitAndLoad(string sceneName, float delay){
yield return new WaitForSecondsRealtime(delay);
SceneManager.LoadScene(sceneName);
}
}
Audio Player Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AudioPlayer : MonoBehaviour
{
[Header("Shooting")]
[SerializeField] AudioClip shootingClip;
[SerializeField] AudioClip shootingClipEnemy;
[SerializeField] [Range(0f, 1f)] float shootingVolume = 1f;
[SerializeField] [Range(0f, 1f)] float shootingVolumeEnemy = 1f;
[Header("Damage")]
[SerializeField] AudioClip hitTakenClip;
[SerializeField] [Range(0f, 1f)] float hitTakenVolume = 1f;
[Header("Music")]
[SerializeField] AudioClip menuMusic;
[SerializeField] AudioClip gameMusic;
[SerializeField] private AudioSource source;
static AudioPlayer instance;
private void Awake() {
ManageSingleton();
}
void ManageSingleton(){
if(instance != null){
gameObject.SetActive(false);
Destroy(gameObject);
}else{
instance = this;
DontDestroyOnLoad(gameObject);
}
}
public void PlayShootingClip(){
PlayClip(shootingClip, shootingVolume);
}
public void PlayShootingClipEnemy(){
PlayClip(shootingClipEnemy, shootingVolumeEnemy);
}
public void PlayHitTakenClip(){
PlayClip(hitTakenClip, hitTakenVolume);
}
static public void PlayMenuMusic(int prevScene){
if(instance != null) {
if(instance.source != null && prevScene != 2){
instance.source.Stop();
instance.source.clip = instance.menuMusic;
instance.source.Play();
}else if(prevScene == 2){
return;
}else{
Debug.LogError("Unavailable MusicPlayer component");
}
}
}
static public void PlayGameMusic(){
if(instance != null) {
if(instance.source != null) {
instance.source.Stop();
instance.source.clip = instance.gameMusic;
instance.source.Play();
}else{
Debug.LogError("Unavailable MusicPlayer component");
}
}
}
void PlayClip(AudioClip clip, float volume){
if(clip != null){
Vector3 cameraPos = Camera.main.transform.position;
AudioSource.PlayClipAtPoint(clip, cameraPos, volume);
}
}
}