Home > Software engineering >  Why does this static Instance return null?
Why does this static Instance return null?

Time:10-05

I have the following class to reference Audio Assets in my game

public class AudioAssets : MonoBehaviour{

private static AudioAssets _Instance;

public static AudioAssets Instance
{
    get
    {
        if (_Instance == null)
        {
            _Instance = (Instantiate(Resources.Load("AudioAssets")) as GameObject).GetComponent<AudioAssets>();
        }
        return _Instance;
    }
}

Unfortunately when I tested this with the following

AudioManager.AudioManagerInstance.PlayClipTest(AudioAssets.Instance.Molotov);

it throws a null exception inside the If statement.

What I am really confused about is I have an identical class GameAssets which has the exact signature as this one and works without a flaw

They are both located inside resources enter image description here

I've tried a lot but I can't get behind why one of these is working but the other isn't. Am I missing something obvious here? Would really appreciate some help!

CodePudding user response:

The Answer

Instantiate(Resources.Load("AudioAssets")) is going to look for a file called AudioAssets in a Resources folder somewhere in the directory tree below Assets folder (see here). If that file does not exist, Instantiate(Resources.Load("AudioAssets")) as GameObject will evaluate as null because of the use of the as keyword. Subsequently, invoking GetComponent<AudioAssets>() on null will result in NullReferenceException.

Side note to avoid other weird issues:

  • Any instances you have that are subclasses of Unity's Object should do null checks on the object itself (Instance == null should actually be !Instance). Otherwise, you might experience unexpected behaviour. See here for more details.
  • Avoid as like the plague. Unless you know there is are valid reasons for the item instantiated to be null and handle it appropriately to avoid a NullReferenceException use an explicit cast instead so the line would be _Instance = ((GameObject)Instantiate(Resources.Load("AudioAssets"))).GetComponent<AudioAssets>();. That way, if it's not able to cast what it tried to load, it will give you a more obvious exception indicating so.
  • Related