- Home /
Using singleton for background music
I'm trying to play background music through multiple scenes by creating a Game Object in my main menu and using the code below:
public class MusicPlayer : MonoBehaviour { private static MusicPlayer instance = null; public static MusicPlayer Instance { get { return instance; } }
void Awake() { if (instance != null && instance != this) { Destroy(instance.gameObject); return; } else { instance = this; }
DontDestroyOnLoad(gameObject);
}
public void Play() { audio.Play(); }
public void Stop() { audio.Stop(); } }
In my Menu script...
void Start () {
MusicPlayer.Instance.Play();
}
The music keeps playing when I go to other scenes, but it stops once I return to the main menu.
Lani, did you ever solve this problem? What you described sounds kind of like a (possible) Unity bug I've been trying to isolate, so I'd be curious to know how this turned out.
Unfortunately, I was not able to fix this. I ended up just making a loading screen and putting the music there. :(
Thank you both for the effort, though! $$anonymous$$uch appreciated :)
Answer by franktinsley · Jun 22, 2012 at 01:15 AM
This is what I finally cobbled together that worked for me.
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(AudioListener))]
[RequireComponent(typeof(AudioSource))]
class Music : MonoBehaviour
{
private static Music instance = null;
public static Music Instance
{
get
{
if (instance == null)
{
instance = (Music)FindObjectOfType(typeof(Music));
}
return instance;
}
}
void Awake ()
{
if (Instance != this)
{
Destroy(gameObject);
}
else
{
DontDestroyOnLoad(gameObject);
}
}
}
Answer by StephanK · Oct 23, 2010 at 08:27 AM
If you use DontDestroyOnLoad(gameMusic) it will "survive" a scene load. In you first script you are destroying the gameMusic object manually every time you load a new scene. If you don't do that it should work.
To use the Singleton pattern just replace the class name with your own. Then add you own code to it. You can now reach this object from every other script using MyClassName.Instance.
Here is the quick and dirty version for you:
[RequireComponent(typeof(AudioSource))] class MusicPlayer : MonoBehaviour { private static MusicPlayer instance = null; public static MusicPlayer Instance { get { return instance; } }
void Awake() { instance = this; DontDestroyOnLoad(gameObject); }
public void Play() { audio.Play(); }
public void Stop() { audio.Stop(); } }
If you attach this script to your gameMusic object the object shouldn't be destroyed and you can start stop your music by calling MusicPlayer.Instance.Play() from any script.
You don't "connect" it to the Singleton, your music gameObject IS the singleton.
Err.. I'm sorry, but where am I supposed to put "game$$anonymous$$usic"? I edited my original post to what I have now.
Thank you, spree! It's looking a lot better now. But for some reason, whenever I go back to the menu, the music actually stops. And if I go to a different scene and come back, it'll play again. I changed my original post to show you what I have right now.
That's because every time your menu script starts up it restarts your $$anonymous$$usicPlayer. You should check if the audio is already playing before you start it. You can use audio.IsPlaying for that.
Answer by cozmoziz · May 03, 2011 at 06:32 PM
Messing around with the code a bit and testing with my game I have found the code below to work. The music plays throughout all scenes and doesn't start and stop when going in and out of the menu. I also just Play the music within the class for when the instance first gets set to this. Don't know if this is sloppy c# coding, but still just getting my feet wet with this language.
using UnityEngine; using System.Collections;
[RequireComponent(typeof(AudioSource))] class MusicPlayer : MonoBehaviour { private static MusicPlayer instance = null; public static MusicPlayer Instance { get { return instance; } }
void Awake() { Debug.Log("instance = " + this); if (instance != null){ Debug.Log("inside the instance != null if statement doing nothing"); return; } else { instance = this; DontDestroyOnLoad(gameObject); Play(); } }
public void Play() { audio.Play(); }
public void Stop() { audio.Stop(); } }