Unity | 工具类:单例总结

目录

一、常规单例

二、Unity单例

1. MonoBehaviour单例

2.Simple单例


一、常规单例

        常规的单例模式是指在普通类中实现单例模式的方式,而不依赖于任何框架或引擎。这种单例模式在许多编程语言中都非常常见,其主要特点是:

  1. 单例类有一个私有的静态变量来保存唯一实例
  2. 提供一个公有的静态方法(通常是 Instance 方法)来获取唯一实例
  3. 将构造函数定义为私有,防止外部创建新的实例
public class Singleton
{
    // 用来保存唯一的实例
    private static Singleton instance = null;
    // 确保线程安全的锁对象
    private static readonly object lockObj = new object();

    // 私有构造函数,防止实例化
    private Singleton()
    {
    }

    // 获取唯一实例的公有静态方法
    public static Singleton Instance
    {
        get
        {
            // 双重检查锁定(double-checked locking)
            if (instance == null)
            {
                lock (lockObj)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }

    // 单例类中的方法示例
    public void DoSomething()
    {
        Console.WriteLine("Singleton instance is doing something.");
    }
}

二、Unity单例

1. MonoBehaviour单例

        适合在需要动态创建单例对象的场合,并能处理场景切换等复杂情况。

优点:

  1. 懒加载Instance属性只有在第一次访问时才会创建实例,这有助于减少不必要的开销。
  2. DontDestroyOnLoad:使用DontDestroyOnLoad保证实例在在场景切换时不被销毁。
  3. 防止重复创建单例:在销毁时设置mIsDestroying标记,防止对已销毁单例进行重复创建。

缺点:

  1. GameObject创建管理:它通过new GameObject().AddComponent<MonoBehaviourSingleton>()的方式创建实例,这在某些情况下过于灵活,可能导致难以管理和调试。
  2. 静态变量的潜在问题:如果游戏中对于对象销毁和创建的逻辑非常复杂,可能会因为静态变量状态互相干扰造成潜在的问题。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonoBehaviourSingleton : MonoBehaviour
{
    static bool mIsDestroying;               //判断销毁的静态变量
    static MonoBehaviourSingleton mInstance;
    public static MonoBehaviourSingleton Instance
    {
        get
        {

            if (mInstance == null)
            {
                if (mIsDestroying)
                {
                    Debug.LogWarning("[MonoBehaviourSingleton] Instance '" + typeof(MonoBehaviourSingleton) +
                                     "' already destroyed. Returning null.");
                    return null;     //如果已销毁则跳出,防止嵌套调用
                }
                mInstance = new GameObject("[MonoBehaviourSingleton]").AddComponent<MonoBehaviourSingleton>();
                DontDestroyOnLoad(mInstance.gameObject);  //创建实例并设置为DontDestroyOnLoad
            }
            return mInstance;
        }
    }

    public void Test()
    {
        Debug.Log("Test");
    }
    void OnDestroy()
    {
        mIsDestroying = true;  //销毁时将标记变量设置为true,防止对已销毁单例进行重复创建
    }
}

2.Simple单例

        更直观简单,但需要确保对象在场景中存在且被正确管理,不适合频繁切换场景的情况。

优点:

  1. 更容易管理:不用手动创建GameObject,更多依赖于Unity编辑器来管理单例对象的创建。
  2. 避免重复实例:通过比较instancethis,可以确保在同一场景中只存在一个实例。

缺点:

  1. 缺乏灵活性:不能像前一种方法那样灵活创建实例,必须确保在场景中包含该组件对应的对象。
  2. 潜在的实例丢失问题:如果SimpleSingleton对象不在初始场景中,可能会引发问题,如果有依赖该单例的其他代码在实例初始化之前执行,会出现空引用错误。
using UnityEngine;

public class SimpleSingleton : MonoBehaviour
{
    private static SimpleSingleton instance;

    public static SimpleSingleton Instance
    {
        get
        {
            if (instance == null)
            {
                Debug.LogError("Singleton instance has not been set. Make sure the singleton is properly instantiated.");
            }
            return instance;
        }
    }

    protected virtual void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else if (instance != this)
        {
            Destroy(gameObject);
        }
    }

    public void Test()
    {
        Debug.Log("Test");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值