单例模式(Singleton Pattern)【创建型】__MonoSingleton,及 相关应用(TimerManager)

Unity单例模式模板类 Unity单例模式模板类,以供学习,有两个: 一个单纯的Singleton 一个MonoSingleton,继承于MonoBehaviour 立即下载

如果项目中有很多个单例,那么我们就必须每次都写这些代码,有什么办法可以省去这些不必要的代码呢?

 

using UnityEngine;

/// <summary>
/// Be aware this will not prevent a non singleton constructor
///   such as `T myT = new T();`
/// To prevent that, add `protected T () {}` to your singleton class.
/// 
/// As a note, this is made as MonoBehaviour because we need Coroutines.
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;

    private static object _lock = new object();

    public static T Instance
    {
        get
        {
            if (applicationIsQuitting)
            {
                Debug.LogWarning("[Singleton] Instance '" + typeof(T) +
                                 "' already destroyed on application quit." +
                                 " Won't create again - returning null.");
                return null;
            }

            lock (_lock)
            {
                if (_instance == null)
                {
                    _instance = FindObjectOfType<T>();

                    if (FindObjectsOfType<T>().Length > 1)
                    {
                        Debug.LogError("[Singleton] Something went really wrong " +
                                       " - there should never be more than 1 singleton!" +
                                       " Reopenning the scene might fix it.");
                        return _instance;
                    }

                    if (_instance == null)
                    {
                        GameObject singleton = new GameObject();


                        _instance = singleton.AddComponent<T>();
                        singleton.name = "(singleton) " + typeof(T).ToString();

                        DontDestroyOnLoad(singleton);

                        Debug.Log("[Singleton] An instance of " + typeof(T) +
                                  " is needed in the scene, so '" + singleton +
                                  "' was created with DontDestroyOnLoad.");
                    }
                    else
                    {
                        //Debug.Log("[Singleton] Using instance already created: " + _instance.gameObject.name);
                    }
                }

                return _instance;
            }
        }
    }

    private static bool applicationIsQuitting = false;
    /// <summary>
    /// When Unity quits, it destroys objects in a random order.
    /// In principle, a Singleton is only destroyed when application quits.
    /// If any script calls Instance after it have been destroyed, 
    ///   it will create a buggy ghost object that will stay on the Editor scene
    ///   even after stopping playing the Application. Really bad!
    /// So, this was made to be sure we're not creating that buggy ghost object.
    /// </summary>
    protected virtual void OnDestroy()
    {
        applicationIsQuitting = true;
    }
    public virtual void Awake()
    {
        if (gameObject.transform.parent == null)
            DontDestroyOnLoad(gameObject);
    }

}

应用: TimerManager——单例协同

 

using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine.Events;

public class TimerManager : MonoSingleton<TimerManager> {

    public delegate void TimeoutEventDelegate(params object[] arr);

    public class Timer
    {
        CrudeElapsedTimer _TimerEntity;
        TimeoutEventDelegate _Callback;
        object[] _Params;


        public Timer(float timesec, TimeoutEventDelegate cb, params object[] arr)
        {
            _Params = arr;
            _Callback = cb;
            _TimerEntity = new CrudeElapsedTimer(timesec);
        }

        public bool Update()
        {
            if (_TimerEntity != null)
            {
                _TimerEntity.Advance(Time.deltaTime);

                if (_TimerEntity.TimeOutCount > 0)
                {
                    if (_Callback != null)
                    {
                        _Callback(_Params);
                    }
                    return true;
                }
            }
            return false;
        }
    }


    Dictionary<Type, Timer> _CallbackDic = new Dictionary<Type, Timer>();
    public TimerUpdateEvent _TimerUpdateEvent = new TimerUpdateEvent();

    List<Type> _WillRemove = new List<Type>();
    // Update is called once per frame
    void Update() {
        ClearWillRemove();

        foreach (KeyValuePair<Type, Timer> kv in _CallbackDic)
        {
            bool b = kv.Value.Update();
            if (b)
            {
                _WillRemove.Add(kv.Key);
            }
        }
        ClearWillRemove();

        if (_TimerUpdateEvent != null)
        {
            _TimerUpdateEvent.Invoke();
        }
    }

    void ClearWillRemove()
    {
        foreach (Type t in _WillRemove)
        {
            if (_CallbackDic.ContainsKey(t))
            {
                _CallbackDic.Remove(t);
            }
        }
        _WillRemove.Clear();
    }


    public void AddTimer<T>(float timesec, TimeoutEventDelegate cb, params object[] arr)
    {
        StartCoroutine(AddTimerCoroutine<T>(timesec, cb, arr));
    }
    IEnumerator AddTimerCoroutine<T>(float timesec, TimeoutEventDelegate cb, params object[] arr)
    {

        yield return 0;
        if (!_CallbackDic.ContainsKey(typeof(T)))
        {
            _CallbackDic.Add(typeof(T), new Timer(timesec, cb, arr));

        }
    }

    public void CancelTimer<T>()
    {
        StartCoroutine(CancelTimerCoroutine<T>());
    }
    IEnumerator CancelTimerCoroutine<T>()
    {
        yield return 0;

        if (!_WillRemove.Contains(typeof(T)))
        {
            _WillRemove.Add(typeof(T));
        }
    }


    #region calculate elapsed time tool

    private TimeSpan startTime;
    public void StartTime()
    {
        startTime = DateTime.Now.TimeOfDay;
    }

    /// <summary>
    /// 开始时间
    /// </summary>
    /// <returns>开始时间</returns>
    public TimeSpan StartTimeFlag()
    {
        TimeSpan stf = DateTime.Now.TimeOfDay;
        return stf;
    }

    /// <summary>
    /// 输出经过时间
    /// </summary>
    /// <param name="st">相对应的开始时间</param>
    /// <param name="timeFlag">需要计算的时间标志</param>
    public void LogElapsedTimeFlag(TimeSpan st,string timeFlag = "")
    {
        string te = (DateTime.Now.TimeOfDay - st).ToString();
        Debug.LogFormat("{0} elapse: {1}", timeFlag, te);
    }

    public TimeSpan EndTime(string entFlag = "")
    {
        TimeSpan endTime = DateTime.Now.TimeOfDay;
        return endTime;        
    }
    
    public void LogTimeElapsed(string tag = "")
    {
        string timeElapsed = (DateTime.Now.TimeOfDay - startTime).ToString();
        Debug.LogFormat("{0} !!!!!elapse: {1}", tag, timeElapsed);
    }
    
    #endregion


    #region Call Example

    //void OnTimeout(params object[] arr)
    //{

    //    //do something
    //}
    //TimerManager.Instance.AddTimer<T>(5.0f, OnTimeout);
    //TimerManager.Instance.CancelTimer<T>();


    #endregion
}
public class TimerUpdateEvent : UnityEvent
{
}

 

应用:

TimerManager.Instance.StartCoroutine(Test());

 

PS:MonoBehavior单例

今天我们就来看看在unity中如何使用单例模式,在unity中,我们分两种单例,一种是继承monobehavior的单例,一种是普通单例。

其实在unity中,如果脚本是继承monobehavior,那么使用起单例来更加简单。

只需要在Awake()里面,添加一句instance = this;

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

using UnityEngine;

using System.Collections;

public class test2 : MonoBehaviour {

    public static test2 instance;

    // Use this for initialization

    void Awake () {

        instance = this;

    }

     

    // Update is called once per frame

    void Update () {

 

    }

}

  

2.普通类的单例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

using UnityEngine;

using System.Collections;

public class test2 {

    private static test2 instance;

    public static test2 Instance

    {

        get

        {

            if (null == instance)

                instance = new test2();

            return instance;

        }

        set { }

    }

}

产业园区如何高效对接企业技术需求与高校科研成果?.docx 科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。 立即下载

相关推荐

C# 调用halcon中visualize_object_model_3d显示点云

3.1 判断线程是否为空,如果为空,则新创建,如果不为空,则中断线程,清空窗口后再次执行创建操作3.2 创建:调用show()方法实例化显示类的对象,传入显示参数,将线程testvisual 绑定 在 类对象的action方法上(此处action方法内部,只调用了visualize_object_model_3d算子)3.3 启动线程。

weixin_42362219的博客 1403

MonoSingleton——Unity中的单例模式

Unity中有很多特别的类需要以单例模式呈现,比如全局的UI管理类,各种缓存池,以及新手导航类等等。而Unity中,因为所有继承自Monobehaviour的脚本在实现的时候都是单线程的,所以像网上流传的一些C#的实现方式就显得不那么的实用了。 很多国内的公司所使用的MonoSingleton都是有问题的,比如像Easytouch中关于单例是这样实现中有这样一段代码。 public s

qq_38516478的博客 1万+

【AI实战派】从零部署YOLOv8:香橙派AIpro边缘端目标检测全流程解析

本文详细解析了在香橙派AIpro边缘设备上从零部署YOLOv8目标检测模型的全流程。内容涵盖硬件开箱、环境搭建、模型转换(ONNX到昇腾OM格式)以及编写Python推理脚本,并提供了性能优化与实战技巧,帮助开发者高效实现实时边缘AI应用。

weixin_29183637的博客 329

Unity常用设计模式-单例模式:游戏中的独一无二

当谈到Unity游戏开发时,设计模式是一个非常重要的主题,其中之一就是单例模式。单例模式是一种创建模式,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。在Unity中,单例模式经常用于管理全局游戏状态、资源管理、对象池等方面。在本文中,我们将探讨Unity中如何实现单例模式以及其优势。单例模式在Unity游戏开发中非常有用,它可以确保只有一个实例存在,提供全局访问点,节省资源并确保线程安全。通过遵循上述步骤,你可以轻松地在Unity中实现单例模式,并应用它来管理游戏中的全局状态和资源。

weixin_51186493的博客 1510

别再被网站风控了!手把手教你修改Chromium源码,实现TLS指纹随机化

本文详细介绍了如何通过修改Chromium源码实现TLS指纹随机化,有效规避网站风控。文章深入解析了TLS指纹(如JA3指纹)的工作原理,并提供了具体的源码修改步骤和编译方法,帮助开发者突破高级反爬技术。通过动态打乱加密套件顺序,实现每次请求生成不同的指纹,显著提升自动化工具的隐蔽性。

weixin_28712661的博客 427

ADS学习笔记 2. 低噪声放大器设计

ADS学习笔记 2. 低噪声放大器设计。设计了一个中心频率433MHz,增益18.206dB,NF=0.134dB,S11带宽较好的低噪声放大器

u014087103的博客 9509

[Unity基础] 单例类MonoSingleton 和普通单例Singleton

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace Common { //namespace 域名.项目名称.模块 /// <summary> /// 脚本单例工具类 /// 特点: ///...

qq_21407523的博客 4717

ArcMap学习笔记(三)地图数字化

地图数字化前言地图数字化实现步骤1.加载地形图2.新建要素图层3.开启编辑环境4.设置捕捉环境5.选择数字化图层6.数字化控制点7.数字化等高线8.数字化图幅边框9.保存数字化成果总结 前言 使用软件:ArcMap10.4.1中文版 如果出现侵权,请在评论留言,我会及时删除,谢谢。 地图数字化 空间数据采集(输入)是将现有的地图、外业观测成果、航空像片、遥感图片数据、文本资料等转换成GIS可以直接...

JayWang博客 1万+

设计模式之单例模式

单例模式(Singleton Pattern)是设计模式中的一种创建型模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

qq_39144436的博客 1312

Qt C++ 的虚拟演播室系统

**数据流转**:OpenCV 处理的图像格式通常是 `cv::Mat`,而 Qt 3D 渲染需要 `QImage` 或 `QTexture2D`。// 临时用颜色代替。// 前景在背景前面。#### 3.3 主窗口与 Qt 3D 集成 (`mainwindow.h` / `.cpp` / `.ui`)* **更复杂的 3D 场景**:加载 3D 模型(.obj, .gltf 等)作为背景和道具。1. **构建项目**:确保 `.pro` 文件中的 OpenCV 路径配置正确,然后构建项目。

寒寒豆豆软件公司的博客 112

fasterlio原理及代码框架梳理

Faster-LIO 的优势是在保持同等高精度的前提下,显著提升计算效率,以支持更极端的应用场景(如高速无人机)和更廉价的硬件平台。可以把 Faster-LIO 理解为用一把更快的“空间哈希筛子”(iVox)替换了原来精细的“动态平衡树”(ikd-Tree),从而在精度损失极小的情况下,实现了效率的显著提升。:只在实际有地图点的空间区域动态创建和保留体素单元,形成一个稀疏的体素地图。是关键:将去畸变点云中的每个点,在 iVox 维护的局部地图中搜索近邻(如5个最近点),构建点到面的距离残差。

Studying…… 246

【Unity】Unity开发进阶(四)Unity脚本单例工具(必备工具)

在Unity场景中,经常有很多脚本需要引入,而这些脚本中,有很大一部分都是只需要引用一次,也只需要进行一次实例化,此时我们可以提供一个工具用于自动获取该脚本的实例对象,并保证全场景中只包含这一个实例,还能在脚本未被引入时实现自动引入脚本。这是一个非常实用的工具,几乎每个项目都会用到。 该工具的特点: 自动获取该脚本的实例对象。 保证全场景中只包含这一个实例。 在脚本未被引入时实现自动引入脚本。 具体代码如下: /// <summary> /// Mono脚本单例工具 /// 使用场景:所有在

一个普普通通的游戏开发者 1980

LeRobot 入门教程(十一)π0(Pi0)π0.5(Pi0.5)训练、推理、部署

本文介绍了Physical Intelligence公司开发的π₀和π₀.₅系列通用机器人控制视觉-语言-动作模型。π₀作为首款基础模型,融合流匹配、跨实体训练等技术,支持50Hz高频控制。π₀.₅是其升级版,通过异构数据协同训练解决开放世界泛化问题,在Libero基准测试中表现优异。文章详细说明了两个模型的安装要求、使用方法、训练策略及关键参数配置,包括混合精度训练、梯度检查点等优化技术,为机器人在多样化场景中的语义理解和动作控制提供了完整解决方案。

2506_90492529的博客 5039

【unity基础框架】单例基类

单例模式,需要用到单例的继承这个基类。一个继承mono一个不继承mono。

weixin_61943345的博客 351

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Unity 单例模式框架(XXXManager)

一、在游戏开发中最常用的一种框架XXXManager(单例) XXXManager是场景中唯一的,传统的方式为声明一个公开的属性,属性类型为自身,在Awake时对自身引用指定对象为自身。 public class Test1 : MonoBehaviour { private static Test1 instance; public static Test1 Instance { get { return instance; } } pri

weixin_39140087的博客 804

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

单例_MonoSingleton/NormalSingleton

1、基于MonoBehaviour创建单例模板 using UnityEngine; public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour { private static T _single; public static T Single { get { if (_single == null) { ...

会飞的牛 420

Unity之C#学习笔记(16):单例模式及单例模板类 Singleton and MonoSingleton

前篇链接:Unity之C#学习笔记(15):特化委托Action, Func和Lambda表达式 从这节开始,我们来讲几个在游戏设计中非常实用的设计模式,先看单例模式。还是从一个实例入手。 在游戏设计中,通常会采用模块化的设计思想,将游戏功能分解成多个具体的功能模块,并用一个Manager类脚本来管理实现该模块下的功能,比如总管全局的GameManager,管理UI的UIManager,管理声音的AudioManager等等。通常,这些脚本会绑定到一个作为载体的空物体上。既然是管理者,这些类只需要也只应该有

アルタイル 1989

Unity中的MonoSingleton<T>与Singleton<T>

本文的MonoSingleton与Singleton说明。

weixin_74371035的博客 573

Unity 游戏框架搭建 2017 (十四) 优雅的 QSingleton (二) MonoSingleton单例实现

MonoSingleton.cs namespace QFramework.Example { using System.Collections; using UnityEngine; class Class2MonoSingleton : QMonoSingleton { public override void OnSingleto

凉鞋的笔记 794

C#单例模式使用

1、什么是单例单例模式(Singleton)是几个创建模式中最对立的一个,它的主要特点不是根据用户程序调用生成一个新的实例,而是控制某个类型的实例唯一性,通过上图我们知道它包含的角色只有一个,就是Singleton,它拥有一个私有构造函数,这确保用户无法通过new直接实例它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()方法负责检验

IT你我 7920

Unity设计模式(1)泛型单例模式

单例模式反映了封装,分而治之的思想,便于开发者与团队间进行项目管理,将一段‘重复的功能代码’封装成一个独立的整体(如~Manager),从而实现部分功能代码的隔离,增强了代码的可读性与健壮性。也许你的项目里现在已经有了很多单例脚本,在某一个瞬间,你忽然发觉自己写过单例脚本里的代码竟然是相同的,这时,深谙面向对象之道的你灵机一动,一拍脑门,哎!在开发过程中经常将继承了泛型单例的基类的单例类脚本作为~Manager来使用,使声明单例的(通常情况下的)固定代码可复用。,另一种是继承了MonoBehevior的。

xxxxx666666的博客 1281

四。Singleton模式与MonoState模式 -- 强制单例

一。 Singleton模式单态定义:Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这

JJ0320的专栏 506

实现单例类脚本MonoSingleton

继承了MonoSingleton 的类 就是单例类了。

weixin_42137574的博客 223

UnitySingleton核心组件解析:Singleton、MonoSingleton与PersistentMonoSingleton区别与应用

UnitySingleton是Unity项目中实现单例模式的最佳方案,提供了三种核心组件帮助开发者轻松管理全局对象。本文将深入解析Singleton、MonoSingleton与PersistentMonoSingleton的区别及适用场景,让你快速掌握Unity单例模式的正确使用方法。 ## 单例模式在Unity中的价值 在Unity开发中,单例模式是管理全局状态、服务和管理器类的常用设计模

gitblog_00418的博客 1056

c# singleton

using UnityEngine;   /// summary>   /// Be aware this will not prevent a non singleton constructor   ///   such as `T myT = new T();`   /// To prevent that, add `protected T () {}` to your singl

yaokang522的专栏 738
上一篇: UGUI 监听鼠标移入、移出
下一篇: ScrollRect滑动优化(三)_拖动ScrollRect结束时停靠在物体的中心位置
Le_Sam
博客等级 码龄11年 342粉丝 53原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值