日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Unity的MonoBehaviour单例设置

發布時間:2023/12/29 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Unity的MonoBehaviour单例设置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Unity的MonoBehaviour單例設置

    • MonoBehaviour的基本單例模式
    • MonoBehaviour單例的泛型基類
    • MonoBehaviour單例腳本的問題
    • 解決方案
      • 互斥鎖Mutex
      • 使用Editor.OnEnable()監測
        • 想法
        • 實現
    • 參考鏈接

MonoBehaviour的基本單例模式

根據Unity的MonoBehaviour腳本創建單例模式,我們一般的創建方式是:

using UnityEngine;public class MonoSingleton : MonoBehaviour {public static MonoSingleton Instance = null;protected virtual void Awake(){Instance = this;} }

MonoBehaviour單例的泛型基類

使用泛型之后是:

using UnityEngine;public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> {public static T Instance = null;protected virtual void Awake(){Instance = this as T;} }

MonoBehaviour單例腳本的問題

但這樣是有問題的單例模式,在其他的文章中提到單例模式的原則(目的)是“保證一個類只有一個實例,并提供全局訪問點”。
根據上面所述,對比我們這里創建的MonoBehaviour類的單例并沒有對MonoBehaviour類的構造函數進行非公有化,我們依然可以自由的創建該類的實例對象。因為MonoBehaviour類有可視化操作的特點(手動拖拽到場景GameObject上),這部分是Unity內部封裝的,為了不出現不必要的錯誤,我們不能從根本上(即Unity的內部)改變這點。

解決方案

互斥鎖Mutex

經過查找資料,找到不少方法,但似乎效果都不是很理想,或者說不是我想要的效果。但這里我還是分享一個看起來不錯的方式:就是使用互斥類Mutex(互斥鎖),代碼如下,

/// <summary> /// Unity的Mono單例基類 /// </summary> /// <typeparam name="T">對應的子類</typeparam> public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T> {private static T m_Instance = null;private new static string name;private static Mutex mutex;//互斥類Mutexpublic static T Instance{get{if (m_Instance == null){if (IsSingle()){m_Instance = new GameObject(name, typeof(T)).GetComponent<T>();m_Instance.Init();}}return m_Instance;}}private static bool IsSingle(){name = "Singleton of " + typeof(T).ToString();mutex = new Mutex(false, name, out bool createdNew);mutex.WaitOne();return createdNew;}private bool m_isDestroy = true;protected virtual void Awake(){m_isDestroy = true;if (m_Instance == null){if (IsSingle()){m_Instance = this as T;m_Instance.Init();}}else{Debug.LogError("[Singleton] " + typeof(T).Name + " should never be more than 1 in scene!Owner is “" + transform.name + "”.");m_isDestroy = false;Destroy(this);}}protected abstract void Init();protected abstract void DisInit();private void OnDestroy(){if (m_Instance != null){if (m_isDestroy){if (null != mutex){mutex.ReleaseMutex();}m_Instance = null;}DisInit();}}private void OnApplicationQuit(){if (null != mutex){mutex.ReleaseMutex();mutex.Close();mutex = null;}} }

根據互斥鎖Mutex的特點,使將本在程序運行之初,只承認第一個創建的MonoBehaviour單例類,并將多余的的Destroy銷毀掉,只留下一個。
這不失為一種好辦法。

使用Editor.OnEnable()監測

想法

我想的是MonoBehaviour單例類腳本,在編輯器狀態下,被手動拖拽到GameObject上之時,便能識別,場景中是否已經存在該單例類;如果已存在則不會再將該腳本創建(拖拽)到任何GameObject上。
而這種操作就只能在UnityEditor庫下,每個MonoBehaviour腳本對應的Editor中才能實現。

實現

我經過多次嘗試,終于實現了以上描述的效果,即在Editor的OnEnable()函數中實現,代碼如下:

using UnityEditor; using UnityEngine;[CustomEditor(typeof(*****), true), CanEditMultipleObjects] public class MonoSingletonEditor : Editor {private static ***** tInstance = null;protected ***** sMono;protected virtual void OnEnable(){sMono = ((*****)target);if (null == tInstance){tInstance = sMono;}else if (sMono != tInstance){DestroyImmediate(target);Debug.LogError("There can only be one in this script scenario!");return;}} }

代碼中的 “ ***** ” 是對應的MonoBehaviour單例腳本名,而且這也用到了Unity內部封裝的一些函數,故這種方式是無法泛型的。每一個MonoBehaviour單例就要有一個相對的該類。
但經過我測試,也確實是實現了我上面描述的效果,再結合互斥鎖Mutex的泛型基類,就可以很好的防止該類被多次創建。

參考鏈接

https://www.cnblogs.com/fastcam/p/5924036.html

總結

以上是生活随笔為你收集整理的Unity的MonoBehaviour单例设置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。