1
\$\begingroup\$

[Context] I am developing a game in Unity, and wanted to make a Game Manager. Like many examples out there, it uses a Singletron design pattern. But i have several other Managers, all using Singletron pattern, so i decided to make a Singletron base class and make all the managers derive from it. When trying to access the Instance property declared in Base Class within one method in Game Manager derived class, the Instance property refers to the Singletron base class, which is expected.

But it`s not the behaviour i need. I have tried to look for alternatives, but everytime i found a possible solution, i have to declare the member variables/properties in the derived class, and there would be no need to a Singletron Base Class.

I have also looked for generic alternatives (Singletron < T >) but it was not clear how to use these without the need of another script calling it, which would be nonsense since the Game Manager should be the object to manage the game. I could use something like a root game object to creat the managers is instances, but it feels like a ugly and inelegant solution.

The managers are all coded, and this refactor would improve code maintenance, in future.

[Code from Singletron Base Class]

public abstract class Singletron : MonoBehaviour
{
    public static Singletron Instance { get; protected set; } 

    protected virtual void Awake ()
    {
        if (Instance == null) {
            Instance = this;
        } else {
            Destroy (gameObject);
        }

        DontDestroyOnLoad (gameObject);
    }
}

[Pertinent code from Game Manager Derived Class]

public class GameManager : Singletron
{
    public List<GameObject> gameObjectsList;

    public static void SomeMethod()
    {
        foreach (GameObject go in Instance.gameObjectsList) 
        {
            go.DoSomething();
        }
    }
}

[Question] What can i do inside Singletron Base Class to make the Instance.gameObjectList refers the actual class (in example, Game Manager Derived Class) so that i could use the gameObjectsList? Should i cast it to the pertinent manager inside the method (which seens like an inneficient option)?

Thanks in advance!

[Edit] Looking into design patterns page in wikipedia, i found another design pattern related to singletron. In my case, each manager follows the singletron pattern, but its somewhat equivalent to my singletron base class following a Multiton Pattern

\$\endgroup\$
2
\$\begingroup\$

After some research, i found these related posts that helped me out:

But their codes seems to have some overkill features. Cleaning it up a bit, i ended up with this code. I noticed that my difficult with the generic elements was not using the where clause to restrain the derived class.

[Code for Singletron Base Class]

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

    protected virtual void Awake ()
    {
        if (Instance == null) {
            Instance = this as T;
        } else {
            Destroy (gameObject);
        }

        DontDestroyOnLoad (gameObject);
    }
}

[Usage in Game Manager Derived Class]

public class GameManager : Singletron<GameManager>
{
    public List<GameObject> gameObjectsList;

    public static void SomeMethod()
    {
        foreach (GameObject go in Instance.gameObjectsList) 
        {
            go.DoSomething();
        }
    }
}

I tested it and works. What do ou guys think of it?

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