Unity框架学习--3

单例模式基类

构造函数私有化,防止外部创建对象

提供一个属性给外部访问,这个属性就相当于是这个类的唯一对象

分为懒汉模式和饿汉模式

不继承MonoBehaviour的单例模式

cs 复制代码
 public static MyUiManager Instance 
    {
        get
        {
            if (instance == null)
            {
                instance = new MyUiManager();
            }
            return instance;
        }
    }

继承MonoBehaviour的单例模式

cs 复制代码
public class MyUiManager : MonoBehaviour
{
    private MyUiManager() { }

    private static MyUiManager instance;

    public static MyUiManager Instance 
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<MyUiManager>();
            }
            return instance;
        }
    }
}

instance = FindObjectOfType<MyUiManager>();

继承 MonoBehaviour 的单例是会挂在游戏场景上的,需要在游戏场景身上寻找到然后赋值

继承与不继承两者初始化的方式不同

继承MonoBehaviour的自动单例模式

cs 复制代码
if (instance == null)
            {
                instance = FindObjectOfType<MyUIManager>();
                //游戏场景中没有创建物体挂在脚本,写代码来自动做这些事情
                if (instance == null)
                {
                    GameObject go = new GameObject("MyUIManager");  //创建游戏对象
                    instance = go.AddComponent<MyUIManager>();  //挂载脚本到游戏对象身上
                }
            }

继承MonoBehaviour的单例模式切换场景的问题

cs 复制代码
if (instance == null)
                {
                    GameObject go = new GameObject("MyUIManager");  //创建游戏对象
                    instance = go.AddComponent<MyUIManager>();  //挂载脚本到游戏对象身上
                }
                DontDestroyOnLoad(instance);   //让游戏对象切换场景时不销毁

不继承MonoBehaviour的单例模式基类

cs 复制代码
/// <summary>
/// 不继承MonoBehaviour 的单例模式基类
/// 作用:继承了这个这个类的类自带单例模式
/// </summary>
public class SingletonPatternBase<T> where T: SingletonPatternBase<T>
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                //where 里面要求含有无参构造函数  where T :new()
                //....单例怎么能有无参构造函数呢
                //instance = new T();
                
                //或者利用反射调用无参构造方法来构造
                instance = Activator.CreateInstance(typeof(T), true) as T;
            }
            return instance;
        }
    }

    //构造方法私有化  private 的话子类也无法继承对象,所以使用protected
    protected SingletonPatternBase() { }

}

继承MonoBehaviour的单例模式基类

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SingletonMonoAutoBase<T> : MonoBehaviour where T:MonoBehaviour
{
    protected SingletonMonoAutoBase() { }

    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<T>();
                if (instance == null)
                {
                    GameObject go = new GameObject(typeof(T).Name);  //创建游戏对象
                    instance = go.AddComponent<T>();  //挂载脚本到游戏对象身上
                }
            }
            return instance;
        }
    }
}

继承MonoBehaviour的单例模式基类切换场景问题

OnDestroy方法中访问单例对象的问题

OnDestroy 方法执行的时候资源会清空,instance 检测为空,自动生成新对象,所以报错

解决办法:

//记录单例对象是否存在,用于防止OnDestory方法中访问单例对象报错

public static bool isExisted { get; private set; } = false;
protected virtual void OnDestroy()

{

isExisted = false;

}

多线程访问单例时会遇到的问题

操作系统 线程锁问题

cs 复制代码
//线程锁。当多线程访问时,同一时刻只允许一个线程访问
    private static object locker = new object();

    //volatile关键字修饰的字段,当多个线程都对它进行修改时,可以确保这个字段在任何时刻呈现的都是最新的值
    private volatile static T instance;

    public  static T Instance
    {
        get
        {
            if (instance == null)
            {
                lock(locker)
                {
                    if (instance == null)
                    {
                        //或者利用反射调用无参构造方法来构造
                        instance = Activator.CreateInstance(typeof(T), true) as T;
                    }
                }
            }
            
            return instance;
        }
    }
相关推荐
垂葛酒肝汤2 小时前
Unity的UGUI的坐标
unity
winlife_2 小时前
让 AI 写敌人状态机,并用脚本化场景验证状态转换正确:funplay-unity-mcp 实战
人工智能·unity·游戏引擎·ai编程·状态机·mcp
tealcwu2 小时前
【Unity实战】Unity IAP 5.3 中实现 Windows Custom Store 实战教程
windows·unity·游戏引擎
unityのkiven2 小时前
工作分享1(26.5.27):基于栈实现全局返回逻辑通用架构设计(适配异步 + 确认弹窗)
游戏·unity·c#·客户端架构
winlife_16 小时前
在 Unity 里用 AI 做游戏:funplay-unity-mcp 从安装到第一次让 AI 改场景
人工智能·游戏·unity·ai编程·claude·mcp
qq_2052790516 小时前
Unity 运行时候会时不时卡顿一下,哪怕是空场景
unity·游戏引擎
美团骑手阿豪20 小时前
Unity UGUI自适应分辨率
unity·游戏引擎
LONGZETECH21 小时前
软硬协同+故障注入:无人机仿真维修与操控仿真底层算法逻辑拆解
大数据·c语言·算法·3d·unity·无人机
winlife_1 天前
让 AI 跑通“调跳跃手感“的完整闭环:funplay-unity-mcp 实战案例
人工智能·unity·游戏引擎·ai编程·mcp·游戏手感
winlife_1 天前
从一句话到可玩原型:用 funplay-unity-mcp 让 AI 搭起完整游戏循环
人工智能·游戏·unity·ai编程·mcp·游戏原型