using UnityEngine; using System; public static class Single { // 유틸 public static DSPhysicsSGT Physics { get { return DSPhysicsSGT.Instance; } } public static DSEventSGT Event { get { return DSEventSGT.Instance; } } } public abstract class MonoSingleton : MonoBehaviour where T : MonoSingleton { private static bool m_bApplicationQuit = false; private static object InstanceLocker = new object(); public bool m_bInitialized = false; public T m_In; public static volatile T m_Instance; public static T Instance { get { #if !UNITY_EDITOR if (true == m_bApplicationQuit) return null; #endif 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 && IsCreatableSingleton(typeof(T))) { instance = new GameObject(typeof(T).ToString()).AddComponent(); // Problem during the creation, this should not happen if (instance == null) { Debug.LogError("Problem during the creation of " + typeof(T).ToString()); } }else if(instance==null && IsCreatableSingleton(typeof(T)) == false) { #if UNITY_EDITOR throw new System.Exception(); #else Debug.LogError("Don't Create New singlton object : " + typeof(T).ToString()); #endif return null; } 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_Instance.m_In = instance; bool act = m_Instance.transform.gameObject.activeSelf; m_Instance.transform.SetParent(GetParent("DSSingletons (Destroy)").transform); m_Instance.OnInitialize(); m_Instance.m_bInitialized = true; var period = System.DateTime.Now - startTime; if (period.TotalSeconds > 1.0f) { var name = m_Instance.ToString(); Debug.LogWarning("Profile Warnning. DSSingletion {" + 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 (instance != null && m_Instance == instance) { m_Instance.OnFinalize(); if(m_Instance.gameObject!=null) GameObject.Destroy(m_Instance.gameObject); m_Instance = null; } } public void CreateSingleton() { } public virtual void OnInitialize() { } public virtual void OnFinalize() { } public virtual void DoDestroy() { OnDestroy (); } // 인스턴스 널체크. public static bool IsNull() { return (null == m_Instance); } void Awake() { Instance.CleanDuplicate(); } void OnDestroy() { Debug.Log("OnDestroy :: " + typeof(T).Name); Destroyed(this as T); } private void OnApplicationQuit() { m_bApplicationQuit = true; Destroyed(this as T); } static GameObject GetParent(string strName) { GameObject pDSRoot = GameObject.Find(strName) as GameObject; if (null == pDSRoot) pDSRoot = new GameObject(strName); return pDSRoot; } public void SetDontDestroy() { if (null == m_Instance) return; if (Application.isPlaying == false) return; GameObject pParent = GetParent("DSSingletons (DontDestroy)"); DontDestroyOnLoad(pParent); m_Instance.transform.SetParent(pParent.transform); } public static void SafeInvoke( Action act ) { if ( Instance != null ) { act(); } } public static bool IsCreatableSingleton(Type type) { return true; } public void CleanDuplicate() { T[] lists = GameObject.FindObjectsOfType(); if(lists.Length>1) { T instance = null; foreach (var item in lists) { if(item.m_bInitialized == true) instance = item; } if(instance!=null) { foreach (var item in lists) { if(item.m_bInitialized==false) { GameObject.Destroy(item.gameObject); } } } } } }