아카이빙/Unity3D

[Unity3D] Singleton 클래스 구현

셩님 2017. 4. 15. 18:08

Unity3D에서 Singleton 클래스 구현

게임개발에서 활용되는 디자인 패턴중 가장 흔하게 볼 수 있는 게 Singleton 패턴이다.


Singleton 클래스란 단 하나의 인스턴스만이 존재해야하는 클래스라고 정의할 수 있으며, 게임개발에서는 흔히 Manager클래스들을 구현할 때 활용된다.


구글링하면 프로그래밍 언어별로 Singleton 클래스 정의하는 법은 쉽게 찾아볼 수 있다.


C#을 주 언어로 활용하는 Unity3D에서는 C#으로 구현된 Singleton클래스를 구현하면 되는데 조금 독특한 점이 있다. 컴포넌트 기반의 개발방법론을 채택한 Unity3D는 모든 GameObject가 MonoBehaviour 클래스를 상속한다.


단 하나의 오브젝트만을 생성해야하는 클래스를 구현해야 하는데, 이때는 MonoBehaviour를 상속받아야 한다. 이에 따라, Unity3D에서는 MonoBehaviour를 상속받는 MonoSingleton과 일반 Singleton 두 가지 방법을 구현해야할 필요가 있다.


싱글턴을 구현하는 법은 워낙 다양하고, 구현방법은 매우 다양하지만 Singleton의 기본 개념만 유지한 채 구현하면 상관없지만, 개발의 편의를 위해 Generic based 클래스로 구현하는 게 좋다.


Singleton.cs

using UnityEngine;

public abstract class Singleton<T> where T : class {

    protected static T instance = null;
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = System.Activator.CreateInstance (typeof(T)) as T;
            }
            return instance;
        }
    }
}


MonoSingleton.cs

using UnityEngine; public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour { protected static T instance = null; public static T Instance { get { instance = FindObjectOfType (typeof(T)) as T; if (instance == null) { instance = new GameObject ("@"+typeof(T).ToString (),                                           typeof(T)).AddComponent<T>(); DontDestroyOnLoad (instance); } return instance; } } }

Generic Singleton클래스와 MonoSingleton 클래스이다.

생성부분에서 차이가 있음.



GameManager.cs

using UnityEngine;

public class GameManager : Singleton<GameManager> {
    public void Call(){
        Debug.Log ("GameManager Call()");
    }
}


SoundManager.cs

using UnityEngine;

public class SoundManager : MonoSingleton<SoundManager> {

    public void Call(){
        Debug.Log ("SoundManager Call()");
    }
}

각각 Singleton과 MonoSingleton을 상속받았다.



SingletonTest.cs

using UnityEngine;

public class SingletonTest : MonoBehaviour {
    
    void Start () {
        GameManager.Instance.Call ();
        SoundManager.Instance.Call ();
    }
}

테스트.잘 작동 된다.