Self creating singleton from a prefab?

Howdy y’all! So I know how to instantiate a prefab and I know how to create a self-creating singleton, but how do you create a self-creating singleton from a prefab?

Here’s the scenario:
I have a prefab with a bunch of game data: references to other prefabs, settings, descriptions, numbers and what not. I would just make an self-creating XML parsing singleton, but I have prefab references that I can’t serialize. I also would just drop the prefab in every scene, but it’s constantly changing and several scripts use the data in it. I’m trying to decrease the places where that data could get screwed with.

Any thoughts? Thanks!

I also had this question and just in case someone else will come across this topic via google here are results of my experiment: it’s practically impossible to implement. Simply because Unity has no idea to which prefab component (the one which will implement singleton logic) is assigned. When you are trying to access instance, you may create object which will be instance of your own implementation… you have no clue what prefabs uses it. If you decide to assign prefab to singleton implementation that means you have to create object from editor and it’s no longer prefab =)

I partially solved the issue by implementing simple CreateIntance method. You pass prefab and transform… this way you just need to assign prefab to what ever component you are using to implement logic and then simply call for example:

  MySingletonPopup.CreateInstance(this.popupPrefab, popupParent.transform);

  public static T CreateInstance(T prefab, Transform transform) {
    if (instance == null)
      instance = Instantiate(prefab, transform);
    return instance;
  }

In case someone has better solution, please update, thanks!

Pretty necro, but may help someone in the future… I use this approach (you can call the “instance” of the singleton from any script, even if it wasn’t instantiated yet):

SelfInstantiatingSingleton.cs (name it whatever you want)

using UnityEngine;

public class SelfInstantiatingSingleton : MonoBehaviour
{

    public static SelfInstantiatingSingleton instance
    {
        get
        {
            if (_instance == null)
            {
                GameObject gObj = new GameObject();
                var tipo = typeof(SelfInstantiatingSingleton);
                gObj.name = "Set name of singleton here";
                DontDestroyOnLoad(gObj);
                gObj.AddComponent<SelfInstantiatingSingleton>();
                _instance = gObj.GetComponent<SelfInstantiatingSingleton>();
            }
            return _instance;
        }
        set
        {
            _instance = value;
        }
    }

    protected static SelfInstantiatingSingleton _instance;

    public void sayHello()
    {
        Debug.Log("Hi there!");
    }

    public void sayGoodbye()
    {
        Debug.Log("Piss off, dude!");
    }

}

To call it from some script, simply use CLASSNAME.instance…

Caller.cs

using UnityEngine;

public class Caller : MonoBehaviour
{
    void Start()
    {
        SelfInstantiatingSingleton.instance.sayHello();

        SelfInstantiatingSingleton.instance.sayGoodbye();
    }

}

It will never be instantiated twice :slight_smile:

While we’re necroing, here’s some variations that allow either an empty object, or an object that can load predefined prefab (or ScriptableObject) data off disk and create a singleton out of it.

Simple Singleton (UnitySingleton):

Some super-simple Singleton examples to take and modify:

Simple Unity3D Singleton (no predefined data):

Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

public void DestroyThyself()
{
   Destroy(gameObject);
   Instance = null;    // because destroy doesn't happen until end of frame
}
1 Like

Couple notes for this code.

  • you should not have a public set, it is selfinstantiating, you should not allow the override of it from other places
  • you do not use the var tipo = typeof(SelfInstantiatingSingleton); it should be removed
  • instead of the two lines of
gObj.AddComponent<SelfInstantiatingSingleton>();
_instance = gObj.GetComponent<SelfInstantiatingSingleton>();

you should have simply

_instance = gObj.AddComponent<SelfInstantiatingSingleton>();