zoukankan      html  css  js  c++  java
  • Unity中的单例

    由于对单例理解的不是很深,所以在我的印象中,例就是一个比较有规范的全局类。

    至于什么多线程可能会有问题,我暂时没接触到。

    1.首先是最简单的了,各种语言都可以写的单例

    C#:

    public class ExpManager
     {
       static ExpManager m_ExpManager = null;

    public static ExpManager GetSingleton() { if (null == m_ExpManager) { m_ExpManager = new ExpManager(); } return m_ExpManager; } }

    2.Unity中的单例

    在Unity中场景的概念分的比较明显,经常有场景间的跳转,而在跳转时会把上一个场景的东西销毁,再创建下一个场景的东西。

    但有些东西却是场景共用的,比如说共用的UI,声音播放器等。这时我们就想要一个不会被销毁的东西来承载这些东西。

    Unity提供了这个函数:

    http://docs.unity3d.com/Documentation/ScriptReference/Object.DontDestroyOnLoad.html

    在NGUI中看UpdateManager这个类,可以看到他的单例的实现,还有如何管理自己的Update函数,比如计时器实现时也要用到Update:

    public class UpdateManager : MonoBehaviour
     {
         public delegate void OnUpdate (float delta);
     
         public class UpdateEntry
         {
             public int index = 0;
             public OnUpdate func;
             public MonoBehaviour mb;
             public bool isMonoBehaviour = false;
         }
     
         public class DestroyEntry
         {
             public Object obj;
             public float time;
         }
     
         static int Compare (UpdateEntry a, UpdateEntry b)
         {
             if (a.index < b.index) return 1;
             if (a.index > b.index) return 1;
             return 0;
         }
     
         static UpdateManager mInst;
         List<UpdateEntry> mOnUpdate = new List<UpdateEntry>();
         List<UpdateEntry> mOnLate = new List<UpdateEntry>();
         List<UpdateEntry> mOnCoro = new List<UpdateEntry>();
         BetterList<DestroyEntry> mDest = new BetterList<DestroyEntry>();
         float mTime = 0f;
     
         /// <summary>
         /// Ensure that there is an instance of this class present.
         /// </summary>
     
         static void CreateInstance ()
         {
             if (mInst == null)
             {
                 mInst = GameObject.FindObjectOfType(typeof(UpdateManager)) as UpdateManager;
     
                 if (mInst == null && Application.isPlaying)
                 {
                     GameObject go = new GameObject("_UpdateManager");
                     DontDestroyOnLoad(go);
                     //go.hideFlags = HideFlags.HideAndDontSave;
                     mInst = go.AddComponent<UpdateManager>();
                 }
             }
         }
     
         /// <summary>
         /// Update the specified list.
         /// </summary>
     
         void UpdateList (List<UpdateEntry> list, float delta)
         {
             for (int i = list.Count; i > 0; )
             {
                 UpdateEntry ent = list[--i];
     
                 // If it's a monobehaviour we need to do additional checks
                 if (ent.isMonoBehaviour)
                 {
                     // If the monobehaviour is null, remove this entry
                     if (ent.mb == null)
                     {
                         list.RemoveAt(i);
                         continue;
                     }
     
                     // If the monobehaviour or its game object are disabled, move on to the next entry
                     if (!ent.mb.enabled || !ent.mb.gameObject.active) continue;
                 }
     
                 // Call the function
                 ent.func(delta);
             }
         }
     
         /// <summary>
         /// Start the coroutine.
         /// </summary>
     
         void Start ()
         {
             if (Application.isPlaying)
             {
                 mTime = Time.realtimeSinceStartup;
                 StartCoroutine(CoroutineFunction());
             }
         }
     
         /// <summary>
         /// Don't keep this class around after stopping the Play mode.
         /// </summary>
     
         void OnApplicationQuit () { DestroyImmediate(gameObject); }
     
         /// <summary>
         /// Call all update functions.
         /// </summary>
     
         void Update ()
         {
             if (mInst != this) NGUITools.Destroy(gameObject);
             else UpdateList(mOnUpdate, Time.deltaTime);
         }
     
         /// <summary>
         /// Call all late update functions and destroy this class if no callbacks have been registered.
         /// </summary>
     
         void LateUpdate ()
         {
             UpdateList(mOnLate, Time.deltaTime);
             if (!Application.isPlaying) CoroutineUpdate();
         }
     
         /// <summary>
         /// Call all coroutine update functions and destroy all delayed destroy objects.
         /// </summary>
     
         bool CoroutineUpdate ()
         {
             float time = Time.realtimeSinceStartup;
             float delta = time - mTime;
             if (delta < 0.001f) return true;
     
             mTime = time;
     
             UpdateList(mOnCoro, delta);
     
             bool appIsPlaying = Application.isPlaying;
     
             for (int i = mDest.size; i > 0; )
             {
                 DestroyEntry de = mDest.buffer[--i];
     
                 if (!appIsPlaying || de.time < mTime)
                 {
                     if (de.obj != null)
                     {
                         NGUITools.Destroy(de.obj);
                         de.obj = null;
                     }
                     mDest.RemoveAt(i);
                 }
             }
     
             // Nothing left to update? Destroy this game object.
             if (mOnUpdate.Count == 0 && mOnLate.Count == 0 && mOnCoro.Count == 0 && mDest.size == 0)
             {
                 NGUITools.Destroy(gameObject);
                 return false;
             }
             return true;
         }
     
         /// <summary>
         /// Coroutine update function.
         /// </summary>
     
         IEnumerator CoroutineFunction ()
         {
             while (Application.isPlaying)
             {
                 if (CoroutineUpdate()) yield return null;
                 else break;
             }
         }
     
         /// <summary>
         /// Generic add function.
         /// Technically 'mb' is not necessary as it can be retrieved by calling 'func.Target as MonoBehaviour'.
         /// Unfortunately Flash export fails to compile with that, claiming the following:
         /// "Error: Access of possibly undefined property Target through a reference with static type Function."
         /// </summary>
     
         void Add (MonoBehaviour mb, int updateOrder, OnUpdate func, List<UpdateEntry> list)
         {
     #if !UNITY_FLASH
             // Flash export fails at life.
             for (int i = 0, imax = list.Count; i < imax; ++i)
             {
                 UpdateEntry ent = list[i];
                 if (ent.func == func) return;
             }
     #endif
     
             UpdateEntry item = new UpdateEntry();
             item.index = updateOrder;
             item.func = func;
             item.mb = mb;
             item.isMonoBehaviour = (mb != null);
     
             list.Add(item);
             if (updateOrder != 0) list.Sort(Compare);
         }
     
         /// <summary>
         /// Add a new update function with the specified update order.
         /// </summary>
     
         static public void AddUpdate (MonoBehaviour mb, int updateOrder, OnUpdate func) { CreateInstance(); mInst.Add(mb, updateOrder, func, mInst.mOnUpdate); }
     
         /// <summary>
         /// Add a new late update function with the specified update order.
         /// </summary>
     
         static public void AddLateUpdate (MonoBehaviour mb, int updateOrder, OnUpdate func) { CreateInstance(); mInst.Add(mb, updateOrder, func, mInst.mOnLate); }
     
         /// <summary>
         /// Add a new coroutine update function with the specified update order.
         /// </summary>
     
         static public void AddCoroutine (MonoBehaviour mb, int updateOrder, OnUpdate func) { CreateInstance(); mInst.Add(mb, updateOrder, func, mInst.mOnCoro); }
     
         /// <summary>
         /// Destroy the object after the specified delay in seconds.
         /// </summary>
     
         static public void AddDestroy (Object obj, float delay)
         {
             if (obj == null) return;
     
             if (Application.isPlaying)
             {
                 if (delay > 0f)
                 {
                     CreateInstance();
     
                     DestroyEntry item = new DestroyEntry();
                     item.obj = obj;
                     item.time = Time.realtimeSinceStartup + delay;
                     mInst.mDest.Add(item);
                 }
                 else Destroy(obj);
             }
             else DestroyImmediate(obj);
         }
     }
  • 相关阅读:
    [RxJS] throwIfEmpty
    [Kotlin] I/O readline
    [Kotlin] Generic Functions
    [Kotlin] Generics basic
    [CSS 3] Use Multiple Background Images to Create Single Element CSS Art
    [Kotlin] Visibilities
    [Kotlin] Getter and Setter
    [Kotlin] Enum class
    [Kotlin] Singleton Object
    面试问Redis集群,被虐的不行了......
  • 原文地址:https://www.cnblogs.com/gameprogram/p/2736856.html
Copyright © 2011-2022 走看看