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
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 aNullReferenceException
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.