Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Memnochdacoder · Dec 08, 2014 at 07:29 PM · audiostaticclasses

Singleton class always returning null

I have a simple singleton that is supposed to be setting up my background music and it's returning null when I try and instantiate it. The script is attached to a GameObject with an audio clip attached to the source.

Script attached to the game object:

 using UnityEngine;
 using System.Collections;
 
 public class GameMusic : MonoBehaviour
 {
         public static GameMusic _instance = null;
     
         public static GameMusic getInstance {
                 get { 
                         if (_instance == null) {
                                 _instance = GameObject.FindObjectOfType<GameMusic> ();
                                 DontDestroyOnLoad (_instance.gameObject);
                         }
                         return _instance; 
                 }
         }
     
         void Awake ()
         {
                 if (_instance == null) {
                         _instance = getInstance;
                         DontDestroyOnLoad (_instance);
 
                 } else if (this != _instance) {
                         Destroy (this.gameObject);
 
                 }
         }
 }

When trying to access the instance:

 public class AdjustSettings : MonoBehaviour
 {
 
         public Texture settingsMenu;
         public Font customFont;
         public GUIStyle backButtonStyle = null;
         public float hSliderValue = 0.0f;
         public static GameMusic gameMusic;
     
         public void OnGUI ()
         {
                 
                 GUI.DrawTexture (new Rect (0, 0, Screen.width, Screen.height), settingsMenu);
                 setupStyles ();
                 Settings ();
         }
     
         public void Settings ()
         {
                 float buttonXPos = Screen.width / 2;
                 float buttonYPos = Screen.height / 2;
                 float buttonWidth = 100;
                 float buttonHeight = 30;
         
                 if (GUI.Button (new Rect (buttonXPos - 50, Screen.height - 50, buttonWidth, buttonHeight), "", backButtonStyle)) {
                         Application.LoadLevel ("SettingsMenu");
                 }
 
                 hSliderValue = GUI.HorizontalSlider (new Rect (buttonXPos, buttonYPos, 100, 100), hSliderValue, 0.0f, 1.0f);
                 gameMusic.audio.volume = hSliderValue;
 
         }
     
         public void setupStyles ()
         {
                 if (backButtonStyle == null) {
                         backButtonStyle = new GUIStyle (GUI.skin.button);
                         backButtonStyle.font = customFont;
                         backButtonStyle.hover.textColor = Color.yellow;
                         backButtonStyle.fontSize = 20;
                 }
         }
 
         void Awake ()
         {
                 gameMusic = GameMusic.getInstance;
                 if (gameMusic == null)
                         Debug.Log ("The gameMusic instance is set to null.");
         }
 }



Any help would be appreciated.

PS, This is my first time posting here so please forgive any omissions as I'm certain they are unintentional and thank you!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Bunny83 · Dec 08, 2014 at 07:33 PM

Well, it's most likely that your AdjustSettings Awake is called before your GameMusic Awake function. Another possible reason is that you don't have a GameMusic script attached to any object or that object is disabled.

You might want to either setup your script execution order in the settings or change the Awake method in AdjustSettings into Start which is called after all Awake has been called.

edit
I just had another look at your singleton code. I think it would be better to implement your Awake like this:

 void Awake ()
 {
     if (_instance == null)
     {
         _instance = this;
         DontDestroyOnLoad (_instance.gameObject);
     }
     else if (this != _instance)
     {
         Destroy (this.gameObject);
     }
 }

I'm pretty sure that inside of Awake while loading the scene FindObjectOfType can't find the instance. It's also not necessary since in Awake you can use "this".

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Memnochdacoder · Dec 08, 2014 at 08:55 PM 0
Share

Changing to Start() didn't help, still getting null. I'm presu$$anonymous$$g that my implementation of the static class isn't the issue?

avatar image Bunny83 · Dec 08, 2014 at 09:11 PM 0
Share

@$$anonymous$$emnochdacoder: First of all that class isn't static. You still need an instance in the scene. If there is no instance on a GameObject somewhere in your scene, FindObjectOfType can't find anything.

So as i said in my answer are you sure you actually have the Game$$anonymous$$usic script attached to a GameObject in the scene? If not you either have to attach the script to a GameObject or change your "singleton" to support lazy initialization. There are different ways to implement that and it depends on if it's enough to just add the script to an empty gameobject or if your object is based on a prefab.

avatar image Memnochdacoder · Dec 08, 2014 at 09:18 PM 0
Share

alt text

Attached is the screen shot of the game object that has the script attached. I may be doing this completely wrong and if so would like to know the correct way to set this up. In the long run all I'm trying to do is get the background audio to play across all my scenes and attach a volume slider in a settings menu to keep the in game volume level set.

Thank you for your responses by the way, I really do appreciate the help.

screen shot 2014-12-08 at 2.15.05 pm.png (48.2 kB)
avatar image Bunny83 · Dec 08, 2014 at 09:34 PM 0
Share

@$$anonymous$$emnochdacoder: I edited my answer.

avatar image Memnochdacoder · Dec 08, 2014 at 10:08 PM 0
Share

Stepped through with the debugger and found that _instance = GameObject.FindObjectOfType (); doesn't find the object reference. Which I would be ecstatic about if I knew why.

Show more comments
avatar image
0

Answer by fafase · Dec 08, 2014 at 07:41 PM

You 'd rather go for a Singleton class:

 public class SingletonMonoBehaviour<T>:MonoBehaviour where T : MonoBehaviour
 {
     protected T instance = null;
     public T Instance{
         get{
              if(instance == null)
              {
                    instance = (T)FindObjectOfType(typeof(T));
              }
              return instance;
         }
     }
 }

This is a basic implementation that does not prevent multi instances. You can still add a check in the Awake or OnEnable but it needs to be called if Awake is overriden:

 protected virtual void Awake(){
     if(FindObjectsOfType(typeof(T)).Length > 1){
          Debug.LogError("Multiple instances of " this.GetType());
     }
 }

This will only inform, some implementation destroy the extra one, well, I consider this wrong since if you have two instances, you cannot know which will be destroy. If one have data set in the inspector and one is added by mistake, the second may be run first and the first is destroyed and bam you are running a game that goes wrong and you do not know why... Just my view.

Then for any class you can use:

 public class MyClass:Singleton<MyClass>{}

without rewriting the same code over many classes.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Memnochdacoder · Dec 08, 2014 at 08:56 PM 0
Share

In an attempt to get past this issue I implemented what you have above and I'm still getting a null pointer error on the call. $$anonymous$$ore than happy to try just about anything at this point just to get this audio to play in the scenes.

avatar image
0

Answer by Mapleman · Dec 11, 2014 at 07:38 AM

I really don't see the need for singleton class here. I'v set up my background music basicly the same way you are trying to do it, but without any singleton stuff. So, since you have your Audio gameobject, why don't just call DontDestroyOnLoad(gameObject) on Awake without any extra stuff? This way you can put your Audio gameobject on your main/start scene and it will be preserved over different scenes.

Then it's easy to access the components of your Audio-object by using GameObject.FindWithTag(...)

Or even better I think is to use some kind of notification system to control volume etc. I'm using this:

http://wiki.unity3d.com/index.php/NotificationCenter3_5

Sorry if I misunderstood your question or the need for the singleton...

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Dec 11, 2014 at 07:41 AM 0
Share

Well, i think that he wants to have the gameobject in multiple scenes which of course will cause problems in combination with DontDestroyOnLoad due to possible duplicates. The best solution is probably to have the BG$$anonymous$$ script in a loading scene once. An alternative would be a lazy initilaized prefab based singleton class.

avatar image Mapleman · Dec 11, 2014 at 08:19 AM 0
Share

I still don't see the point :) Anyway, if you don't call DontDestroyOnLoad, the music will stop and start all over again. But if you try to just preserve the class by calling DontDestroyOnLoad(this), it actually preserves the whole gameobject and you'll end up with multiple instances. Singleton pattern in general doesn't make much sense in Unity, since if you have non-static members in your class they will be initialised on every scene switch because unity will create a new instance of that class (if attached to gameobject) no matter what if it isn't static.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

How do I make an instance of a class global??? 1 Answer

Probably Dumb Question: Update(), Start(), etc. Don't Work Inside Classes (JavaScript)...? 2 Answers

How to list all the properties and methods from the class? 1 Answer

Is there anything wrong with using lots of static classes? 1 Answer

How to find audioclip in scene 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges