- Home /
Setting singleton assets through inspector
So, I was trying to add a NGUI's UIFont prefab into my singleton. Only to find out it's not that easy.
I could add the prefab on Resources
and initialize it on Start
. That would work. But I didn't want to do it like this because then I'll have to "lock" the prefab name to a string.
Rather, I was trying to figure out a way to do it on the Inspector. Then I got stuck. It simply doesn't work. Maybe it's a bug. If I add my singleton into a scene, the default values for language
will load just fine. But when it's instantiated through script, nada.
Anyway, now here I am. Don't even know what'd be the best approach to do it.
Is this a failure on the Singleton design?
I mean, we can and should set up most singleton variables on the source code itself. But for some assets it seems to make more sense to do it on the Inspector. I just can't picture how.
Answer by Bunny83 · Sep 18, 2013 at 08:57 PM
You can use a prefab-based-singleton. It requires you to place the singleton class on a prefab inside a resources folder to ensure that the prefab is included in the build.
You have to change the "Singleton" class to not create an empty GameObject but instead use Resources.FindObjectsOfTypeAll to instantiate the prefab
This seems to be almost perfect! Still troublesome if there is more than one type... Right now, I'll just throw a warning about it but, do you know if we can assign it somehow?
No, in Unity you can always create multiple versions of an asset. Since serialized data can only be stored in assets it's not possible to prevent multiple instances.
Not sure if you got what I meant. I wanted to assign the object from resource into the singleton somehow. So even if there are multiple versions of an asset, I could assign only one. In any case, this mostly solved my problem as it is! And I'll update the wiki after you give me a conclusive answer about this aspect. :)
I'm not sure what you mean by "assign into the singleton". A prefab-based singleton class would look like this:
if (_instance == null)
{
_instance = (T) FindObjectOfType(typeof(T));
if (_instance == null)
{
T prefab = (T)Resources.FindObjectsOfTypeAll(typeof(T));
if (prefab != null)
{
_instance = (T)Instantiate(prefab);
}
else
{
_instance = (new GameObject()).Addcomponent<T>();
}
_instance.gameObject.name = "(singleton) " + typeof(T).ToString(); }
DontDestroyOnLoad(_instance.gameObject);
}
}
return _instance;
Yeah, I thought that code wouldn't actually work. Because it is FindObjects
, plural. T prefab
would have to be T[]
. The precise problem I pointed in the first comment, and reason why I'd want to "assign it somehow", ins$$anonymous$$d. But it works. Compiles, at least. Although, I have no clue why, suddenly it stopped working for me. In any case, the problem of finding more than 1 still exists.
By "assign into singleton" I meant like we can assign into a public T
of a normal script - be it on the prefab or on the script inspector window.