블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2731)
Unity3D (814)
Programming (474)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (57)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (51)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
03-28 00:02

Unity Singleton

Unity3D/Script / 2014. 3. 24. 18:36
using UnityEngine;

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
    protected static bool m_bDontDestroyOnLoad = true;
    
    private static bool m_bApplicationQuit = false;
    private static object InstanceLocker = new object();

    private static T m_Instance = null;
    public static T Instance
    {
        get
        {
            if (true == m_bApplicationQuit)
                return null;

            lock (InstanceLocker)
            {
                // Instance requiered for the first time, we look for it
                if (null == m_Instance)
                {
                    T instance = GameObject.FindObjectOfType(typeof(T)) as T;

                    // Object not found, we create a temporary one
                    if (instance == null)
                    {
                        instance = new GameObject(typeof(T).ToString()).AddComponent<T>();

                        // Problem during the creation, this should not happen
                        if (instance == null)
                        {
                            Debug.LogError("Problem during the creation of " + typeof(T).ToString());
                        }
                    }

                    if (instance != null)
                    {
                        Initialize(instance);
                    }
                }

                return m_Instance;
            }
        }
    }

    private static void Initialize(T instance)
    {
        if (m_Instance == null)
        {
            var startTime = System.DateTime.Now;
            m_Instance = instance;

            // 씬 전환 시, 삭제시킬 싱글톤은 부모 객체에 안붙이도록..
            // 싱글톤 시작 시, m_bDontDestroyOnLoad 셋팅 필요.
            if (true == m_bDontDestroyOnLoad)
            {
                GameObject goRoot = GameObject.Find("Singletons") as GameObject;
                if (null == goRoot)
                {
                    goRoot = new GameObject("Singletons");
                    // DontDestroyOnLoad() 등록은 하위 상속받는 쪽에서 하도록 하는 게 나을까?
                    DontDestroyOnLoad(goRoot);
                }
                m_Instance.transform.parent = goRoot.transform;
            }

            m_Instance.OnInitialize();
            var period = System.DateTime.Now - startTime;
            if (period.TotalSeconds > 1.0f)
            {
                var name = m_Instance.ToString();
                Debug.LogWarning("Profile Warnning. Singletion {" + name + "} too long init time : " 
                                 + period.TotalSeconds.ToString("F") + "Seconds");
            }
        }
        else if (m_Instance != instance)
        {
            DestroyImmediate(instance.gameObject);
        }
    }

    private static void Destroyed(T instance)
    {
        if (m_Instance == instance)
        {
            m_Instance.OnFinalize();
            m_Instance = null;
        }
    }

    public void CreateSingleton() { }
    // [Warning] GameObject에 Component로 미리 등록된 상태에서는 OnInitialize() 호출 안됨.
    public virtual void OnInitialize() { }
    // [Warning] GameObject에 Component로 미리 등록된 상태에서는 OnFinalize() 호출 안됨.
    public virtual void OnFinalize() { }
    protected virtual void CheckDontDestroyOnLoad() { }

    private void Awake()
    {
        Initialize(this as T);
    }

    void OnDestroy()
    {
        Destroyed(this as T);
    }

    private void OnApplicationQuit()
    {
        m_bApplicationQuit = true;
        Destroyed(this as T);
    }
}


반응형
Posted by blueasa
, |