继承MonoBehaviour的单例类

本文深入探讨了Unity中实现单例模式的一种方法:MonoSingleton。通过抽象类MonoSingleton<T>,确保了场景中仅存在一个实例,并在场景切换时不被销毁。具体展示了如何继承该单例类并正确重写OnStart方法。

1、MonoSingleton 

using UnityEngine;

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    public bool global = true;
    static T instance;
    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = (T)FindObjectOfType<T>();
            }
            return instance;
        }

    }

    void Start()
    {
        if (global)
        {
            if (instance != null && instance != this.gameObject.GetComponent<T>())
            {
                Destroy(this.gameObject);
                return;
            }
            DontDestroyOnLoad(this.gameObject);
            instance = this.gameObject.GetComponent<T>();
        }
        this.OnStart();
    }

    protected virtual void OnStart()
    {

    }
}

2、继承单例类

using UnityEngine;

public class Test : MonoSingleton<Test>
{
    protected override void OnStart()
    {
        //不能写 void Start(),会重写抽象类的Start
        //想要在Start()函数执行的写在此函数
    }
}

 

继承MonoBehaviour有多种实现方式,以下是几种常见的实现及使用说明: ### 实现方式一 定义一个泛型单例类作为基类,代码如下: ```csharp using UnityEngine; public class UnitySingleton<T> : MonoBehaviour where T : Component { private static T m_Instance = null; public static T Instance { get { if (m_Instance == null) { m_Instance = FindObjectOfType(typeof(T)) as T; if (m_Instance == null) { GameObject obj = new GameObject(); m_Instance = (T)obj.AddComponent(typeof(T)); obj.hideFlags = HideFlags.DontSave; obj.name = typeof(T).Name; } } return m_Instance; } } public virtual void Awake() { DontDestroyOnLoad(this.gameObject); if (m_Instance == null) { m_Instance = this as T; } else { GameObject.Destroy(this.gameObject); } } } ``` 使用时,若需要使用继承MonoBehaviour单例类型,只需要继承`UnitySingleton`即可,如: ```csharp using UnityEngine; public class MusicSingleton : UnitySingleton<MusicSingleton> { public void Show() { Debug.Log("Play Music"); } void Start() { } void Update() { } } ``` 在其他类中使用该: ```csharp public class OtherClass { public void SomeMethod() { MusicSingleton.Instance.Show(); } } ``` ### 实现方式二 另一种泛型基类的实现: ```csharp using UnityEngine; public class Singleton<T> : MonoBehaviour where T : MonoBehaviour { private static T mInstance; public static T GetInstance() { if (null == mInstance) { mInstance = FindObjectOfType(typeof(T)) as T; if (null == mInstance) { GameObject singleton = new GameObject("(singleton)" + typeof(T).ToString()); mInstance = singleton.AddComponent<T>(); DontDestroyOnLoad(singleton); } } return mInstance; } } ``` 使用示: ```csharp public class ClassB : Singleton<ClassB> { public bool mIsLoading = false; } public class ClassA { public static void Go() { Debug.Log(ClassB.GetInstance().mIsLoading); } } ``` ### 实现方式三 通过构造函数和静态属性实现: ```csharp using UnityEngine; public class GameCtrl : MonoBehaviour { #region 继承MonoBehaviour private GameCtrl() { m_Instance = this; Debug.Log("GameCtrl"); } private static GameCtrl m_Instance = null; public static GameCtrl Instance { get { Debug.Log("get"); return m_Instance; } } #endregion private void Awake() { Debug.Log("Awake"); } public void PopHintMsg() { } } ``` 使用时,在其他类中通过`GameCtrl.Instance`来访问并调用其方法,如: ```csharp public class AnotherClass { public void CallPopHintMsg() { GameCtrl.Instance.PopHintMsg(); } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值