IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity 计时器管理类 -> 正文阅读

[游戏开发]Unity 计时器管理类

计时器管理类

开发原因

在项目开发阶段有很多的计时器需求,包括游戏时间计时,验证码时间计时等。如果没有一个计时器管理类,将会非常混乱,为了更好的管理计时器,封装了一个计时器管理类

功能代码解释

TimerMoudle 管理一个计时器,TimerMoudle对外公开的函数及字段如下:

函数解释
Play(bool restart=false)运行计时器(restart表示是否重新开始计时,默认为false继续计时)
Pause()暂停计时器
Stop()停止计时器
Close(bool isDestroy)关闭计时器(isDestroy表示是否完全销毁即不入对象池,默认为false)
OnComplete(Action act)计时器计时结束的回调
OnProgress(Action<float,float> act)计时器计时进度(当前时间,总时间)
TimerMoudle(string _flag,float _maxTimer)构造函数_flag计时器标识符,_maxTimer计时器的时间
ReInit(string _flag,float _maxTimer)计时器重置,在TimerManager中管理
字段解释
flag标识符(只读)
maxTimer计时器最大时间(只读)
curTimer计时器当前时间(只读)
isPlaying计时器是否正在运行(只读)
isLoop是否循环计时(读写)

TimerMoudleExpand TimerMoudle对象的拓展,用于释放计时器

函数解释
Dispose(this TimerManager.TimerMoudle timerMoudle,bool isDestroy=false)isDestroy表示是否销毁计时器即不入对象池

TimerManager 管理所有的TimerMoudle,对外公开的函数如下:

函数解释
CreateTimer(string flag,float timer,bool isPlay=true)创建计时器(标识符,计时器时间,是否直接运行计时器)
DisposeTimer(string flag,bool isDestroy=false)释放计时器(标识符,是否销毁即不入对象池)
GetTimer(string flag)根据标识符得到计时器

注意:TimerMoudle中的Close函数与TimerMoudleExpand中的Dispose函数及TimerManager中的Dispose函数的区别:TimerMoudle中的Close函数表示释放对象中的内存,而TimerMoudleExpand中的Dispose函数及TimerManager中的Dispose函数不仅释放TimerMoudle中的内存,同时也把指向这个对象的引用也给释放了,推荐使用后两种释放方式!!!

源码

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

/// <summary>
/// 计时器管理类
/// </summary>
public class TimerManager : MonoBehaviour
{
    private static TimerManager _instance;
    public static TimerManager instance
    {
        get
        {
            if (_instance==null)
            {
                _instance = GameObject.FindObjectOfType<TimerManager>();
                if (_instance==null)
                {
                    GameObject OBJ = new GameObject("TimerManager");
                    _instance = OBJ.AddComponent<TimerManager>();
                    DontDestroyOnLoad(OBJ);
                }
            }
            return _instance;
        }
    }
    
    /// <summary>
    /// 所有正在使用的计时器字典
    /// </summary>
    private Dictionary<string,TimerMoudle> timerDict = new Dictionary<string, TimerMoudle>();
    /// <summary>
    /// 闲置计时器的池子
    /// </summary>
    private static List<TimerMoudle> timerPool = new List<TimerMoudle>();
    /// <summary>
    /// 池子最大容量
    /// </summary>
    public int poolMaxCount=10;
    /// <summary>
    /// Update事件
    /// </summary>
    private static event Action OnUpdateEvent;
    
    /// <summary>
    /// 创建一个计时器
    /// </summary>
    /// <param name="flag">计时器flag</param>
    /// <param name="timer">计时器时间</param>
    /// <param name="isPlay">是否开始计时</param>
    /// <returns></returns>
    public TimerMoudle CreateTimer(string flag,float timer,bool isPlay=true)
    {
        if (GetTimer(flag)!=null)
        {
            Debug.LogWarning("CreateTimer Error: 创建计时器Flag重复:"+flag);
            return null;
        }
        TimerMoudle timerMoudle = null;
        if (timerPool.Count>0)
        {
            timerMoudle = timerPool[0];
            timerPool.RemoveAt(0);
            timerMoudle.ReInit(flag, timer);
        }
        else
        {
           timerMoudle= new TimerMoudle(flag,timer); 
        }
        if (isPlay&&timerMoudle!=null)
        {
            timerMoudle.Play(true);
        }
        return timerMoudle;
    }

    /// <summary>
    /// 释放计时器
    /// </summary>
    /// <param name="timer">计时器flag</param>
    /// <param name="isDestroy">是否彻底销毁</param>
    public void DisposeTimer(string flag,bool isDestroy=false)
    {
        TimerMoudle timerMoudle = GetTimer(flag);
        if (timerMoudle!=null)
        {
            timerMoudle.Dispose(isDestroy);
        }
    }

    /// <summary>
    /// 得到计时器
    /// </summary>
    /// <param name="flag">计时器flag</param>
    /// <returns></returns>
    public TimerMoudle GetTimer(string flag)
    {
        if (timerDict.ContainsKey(flag))
        {
            return timerDict[flag];
        }
        return null;
    }

    void Update()
    {
        OnUpdateEvent?.Invoke();
    }

    private void OnDestroy()
    {
        OnUpdateEvent = null;
        if (timerDict!=null&&timerDict.Count>0)
        {
            TimerMoudle[] timerMoudles = timerDict.Values.ToArray();
            for (int i = timerMoudles.Length-1; i >=0 ; i--)
            {
                TimerMoudle timerMoudle = timerMoudles[i];
                timerMoudle.Dispose(true);
            }
            timerMoudles = null;
        }
        timerDict = null;
        timerPool.Clear();
        timerPool = null;
    }

    public class TimerMoudle
    {
        private string m_flag;
        private float m_maxTimer;
        private float m_curTimer;
        private bool _isPlaying;
        /// <summary>
        /// 进度回调
        /// </summary>
        private Action<float,float> progressAct;
        /// <summary>
        /// 结束回调
        /// </summary>
        private Action completeAct;

        /// <summary>
        /// 计时器标识符
        /// </summary>
        public string flag
        {
            get{return m_flag;}
            private set { m_flag = value; }
        }

        /// <summary>
        /// 计时器的最大时间
        /// </summary>
        public float maxTimer
        {
            get { return m_maxTimer; }
            private set { m_maxTimer = value; }
        }

        /// <summary>
        /// 当前时间
        /// </summary>
        public float curTimer
        {
            get { return m_curTimer; }
            private set { m_curTimer = value; }
        }

        /// <summary>
        /// 是否正在计时
        /// </summary>
        public bool isPlaying
        {
            get
            {
                return _isPlaying;
            }
            private set
            {
                _isPlaying = value;
            }
        }

        /// <summary>
        /// 是否循环计时
        /// </summary>
        public bool isLoop = false;

        public TimerMoudle(string _flag,float _maxTimer)
        {
            flag = _flag;
            maxTimer = _maxTimer;
            curTimer = 0;
            isPlaying = false;
        }

        public TimerMoudle ReInit(string _flag,float _maxTimer)
        {
            flag = _flag;
            maxTimer = _maxTimer;
            curTimer = 0;
            isPlaying = false;
            OnUpdateEvent -= OnUpdate;
            isLoop = false;
            return this;
        }

        /// <summary>
        /// 计时结束回调
        /// </summary>
        /// <param name="act"></param>
        /// <returns></returns>
        public TimerMoudle OnComplete(Action act)
        {
            completeAct = act;
            return this;
        }

        /// <summary>
        /// 计时进度回调
        /// </summary>
        /// <param name="act"></param>
        /// <returns></returns>
        public TimerMoudle OnProgress(Action<float,float> act)
        {
            progressAct = act;
            return this;
        }
        
        /// <summary>
        /// 打开计时器 
        /// </summary>
        /// <param name="restart">是否重新计时</param>
        /// <returns></returns>
        public TimerMoudle Play(bool restart=false)
        {
            if (restart)
            {
                curTimer = 0;
            }
            isPlaying = true;
            OnUpdateEvent += OnUpdate;
            return this;
        }

        /// <summary>
        /// 计时器暂停
        /// </summary>
        /// <returns></returns>
        public TimerMoudle Pause()
        {
            isPlaying = false;
            OnUpdateEvent -= OnUpdate;
            return this;
        }

        /// <summary>
        /// 计时器停止
        /// </summary>
        /// <returns></returns>
        public TimerMoudle Stop()
        {
            curTimer = 0;
            isPlaying = false;
            OnUpdateEvent -= OnUpdate;
            return this;
        }

        private void OnUpdate()
        {
            curTimer += Time.deltaTime;
            curTimer = curTimer > maxTimer ? maxTimer : curTimer;
            progressAct?.Invoke(curTimer,maxTimer);
            if (curTimer>=maxTimer)
            {
                completeAct?.Invoke();
                if (isLoop)
                {
                    curTimer = 0;
                }
                else
                {
                    OnUpdateEvent -= OnUpdate;
                }
            }
        }

        /// <summary>
        /// 关闭计时器
        /// </summary>
        /// <param name="isDestroy"></param>
        public void Close(bool isDestroy=false)
        {
            Stop();
            flag = null;
            progressAct = null;
            completeAct = null;
            if (isDestroy||timerPool.Count>=instance.poolMaxCount)
            {
                return;
            }
            timerPool.Add(this);
        }

        

    }
}

public static class TimerMoudleExpand
{
    /// <summary>
    /// 释放计时器
    /// </summary>
    /// <param name="timerMoudle"></param>
    /// <param name="isDestroy"></param>
    public static void Dispose(this TimerManager.TimerMoudle timerMoudle,bool isDestroy=false)
    {
        timerMoudle?.Close(isDestroy);
        timerMoudle=null;
    }
}

使用方式

TimerManager.TimerMoudle tm=TimerManager.instance.CreateTimer("TestFlag", 5).OnProgress((float cur, float max) =>
         {
             Debug.Log("TimerFlag  curTime:"+cur+"maxTime:"+max);
         }).OnComplete(() =>
         {
             Debug.Log("TestFlag: Over");
         });

计时器使用结束要记得释放计时器 即tm.Dispose();

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:47:58  更:2021-08-31 15:48:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年2日历 -2025/2/5 21:59:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码