0
\$\begingroup\$

I just came upon programming patterns and learned about singleton. I'm in the process of creating my first game and it contains several managers:

enter image description here

I wanted to implement singleton on each of the managers,but the only way I can think is copy pasting the singleton pattern on each awake method script attached to each manager.

Is there a more efficient way to do it rather than pasting the pattern on each awake method?

\$\endgroup\$
  • \$\begingroup\$ Oh! That sounds simpler than what I have thought thanks! that actually works! \$\endgroup\$ – tcg Aug 1 at 12:04
0
\$\begingroup\$

An effective way to achieve this is to not do it.

You can create a single singleton that will be the entry point and owner of all the other managers. This way, you don't need to add the singleton infrastructure to all of your managers, just to one.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

I have to say this question doesn't demonstrate much research. If you plug "unity singleton" into a search engine, the very first result is the Unify Community Wiki where they show how to make a reusable Singleton via the Curiously Recurring Template Pattern.

Here's a simplified version closer to the Awake style you're describing:

public abstract class Singleton<T> : MonoBehaviour where T :Singleton<T>
{
    public static T Instance { get; private set; }

    private void Awake() {

        if(Instance != null) {
            Debug.LogErrorFormat("Two copies of singleton {0} in the scene: ({1}, {2}). Please ensure only one is present.", 
                (typeof(T)).FullName, Instance.name, name);
            Destroy(gameObject);
            return;
        }

        Instance = (T)this;
    }
}

You can then apply this singleton behaviour to any MonoBehaviour type by deriving from the template:

public class SomeManager : Singleton<SomeManager>
{        
}

Then access its instance with SomeManager.Instance

That said, as Vaillancourt points out, you can skip having many singletons by just having one overall manager that holds references to the others. In this way it behaves like a version of the Service Locator pattern, giving you a common place to re-hook the references if you ever need to change the sub-managers or have more than one:

public class GameManager : Singleton<GameManager> {

    public AudioManager audioManager;
    public PuzzleManager puzzleManager;
    // ...
}

This can help you avoid a common problem we run into with Singletons, where we add multiplayer and suddenly all the systems that used to be globally unique for the only player, now need multiple instances, one for each player. The "manager of managers" gives you a convenient place to parcel out which references to use for each player, and you can look them up with something like GameManager.Instance.GetInventoryForPlayer(2).

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.