Unity3d通用工具类之定时触发器

时隔多日,好不容易挤出点时间来写写博文。不容易,请送我几朵红花,点个赞也行。

 

今天呢,我们主要来扩展下通用工具类==>定时触发器。

 

顾名思义,所谓的定时触发器,就是告诉程序在过多长时间后,我要执行某个特定的任务。

 

比如举个小栗子:

电饭煲,相信大家都用过,当我们出去工作或者上学的时候,我们只要设置下煮饭时间,就可以安心的离开。

 

电饭煲会自动的开始计时工作,等到了你设置的时间后,他就会自动的开始煮饭啊什么的。而你却可以在远在千里的上班。

 

智能化,对就是这样的效果。我们今天就来写写这个智能的小东西。

 

首先在设计这个小功能之前,我们要明白自己需要的是什么?如何设计?

 

1.需要什么:

(1)肯定要有个管理定时器的类,命名TimeTaskManager。(上网查了下定时器英文可以为:TimeTask,所以就取了这个名字)

(2)既然有了这个管理类,那么这个管理类要管理什么东西?对喽,是你所要定时执行的任务。那么这个任务要包含什么东西?

    1.多久时间开始执行任务肯定要,

    2.重复执行间隔(有些任务要定时的重复执行,比如像机器加工厂的机器昼夜重复一个加工动作)

ok,我们命名为TimeTask

 

2.如何设计:

当我们设计一个个有相关联的类的时候,我们可能需要纸笔来打草稿,其实完全不用,学过uml的同学可以新手拈来。这里呢我推荐使用Process On这个工具。在线绘画工具,非常好用。

这里我们边设计边画图:

首先从TimeTask下手,对于这个类,我们要想作为一个任务,而且还是定时的。那么一下就能想到,任务执行用委托。还有程序肯定有许多任务,所以要定义一个id识别这个唯一任务。

那么定时肯定也需要一些变量,

  1.private uint id;//任务id

  2.private uint interval;//间隔多少秒,重复这个任务

  3.private Action action;//无参委托

看到这里,这个Timetask任务类,大致建立好了。

 

哎!细心的同学可能会发现,这个Action委托是个无参委托,那么假如说我的任务方法有带参的怎么办呢?哎,那么问题就来了。

 

那么我再设计一个带一个参数的Timetask<T>类,然后Action<T> action不就行了。那二个参数呢,三个参数呢......?

 

有多少个参数,你都要设计多少个类。

 

所以,对于这样的情况,我们需要把Timetask抽象成一个基类,命名为AbstractTimeTask

 

 

哎!只要我们所有无参带参的TimeTask都继承与AbstractTimeTask抽象类,这样代码的复用性就大大提高了。

设计好了之后,我们编写代码:

 

 

AbstractTimeTask:

using UnityEngine;
using System.Collections;
using System;
#region 模块信息
/*----------------------------------------------------------------
// 模块名:AbstractTimeT
// 创建者:chen
// 修改者列表:
// 创建日期:2015.11.5
// 模块描述//----------------------------------------------------------------*/
#endregion
public abstract class AbstractTimeTask
{#region 字段private uint m_uiTimeId;//任务idprivate int m_iInterval;//任务重复时间间隔,为0不重复private ulong m_ulNextTick;//下一次触发的时间点#endregion#region 属性public uint TimeId{get {return m_uiTimeId;}set {m_uiTimeId = value;}}public int Interval {get { return m_iInterval; }set { m_iInterval = value; }}public ulong NextTick {get{return m_ulNextTick;}set {this.m_ulNextTick = value;}}/// <summary>/// 抽象属性,给子类自定义自己的action委托/// </summary>public abstract Action Action{get;set;}#endregion#region 公有方法/// <summary>/// 抽象方法,给自己自己定义执行委托/// </summary>public abstract void DoAction();#endregion
}

TimeTask:(这里主要先讲无参)

using UnityEngine;
using System.Collections;
using System;
#region 模块信息
/*----------------------------------------------------------------
// 模块名:TimeTask
// 创建者:chen
// 修改者列表:
// 创建日期:2015.11.5
// 模块描述:定时触发任务类
//----------------------------------------------------------------*/
#endregion
public class TimeTask : AbstractTimeTask
{#region 字段private Action m_action;//定义自己的委托#endregion#region 属性public override Action Action{get{return m_action;}set{m_action = value;}}#endregion#region 公有方法/// <summary>/// 重新父类的委托方法/// </summary>public override void DoAction(){m_action();}#endregion
}

  

这里我们增加了NextTick字段,有什么卵用呢?主要是用来与当前程序运行时间比较,如果刚好等于这个NextTick值时,就触发委托函数,执行任务。

细想一下,我们定时管理器类要把任务一个个加到队列里面管理,那么肯定需要一个时间变量与task里面的时间变量进行比较。

所以,定时管理类就需要一个static uint tick变量来记录程序运行总的时间,如果吧task加到队列里面,task的NextTick=程序运行的总的时间tick+start(多久之后执行任务);还有就是如果task的interval的值大于0,也就是说有重复的执行,那么,就需要再加上interval的值,然后再加入到队列里面。

分析了这么多,接着来写管理类:

TimeTaskManager:

using UnityEngine;
using System.Collections.Generic;
using System.Diagnostics;
using System;
#region 模块信息
/*----------------------------------------------------------------
// 模块名:TimeTaskManager
// 创建者:chen
// 修改者列表:
// 创建日期:2015.11.5
// 模块描述:定时触发器管理类
//----------------------------------------------------------------*/
#endregion
public class TimeTaskManager 
{#region 字段private static uint m_uiNextTimeId;//总的id,需要分配给task,也就是每加如一个task,就自增private static uint m_uiTick;//总的时间,用来和task里面的nexttick变量来进行比较,看是否要触发任务private static Queue<AbstractTimeTask> m_queue;private static Stopwatch m_stopWatch;//c#自带的计时器,不会的自行百度private static readonly object m_queueLock = new object();//队列锁#endregion#region 构造方法private TimeTaskManager(){}static TimeTaskManager(){m_queue = new Queue<AbstractTimeTask>();m_stopWatch = new Stopwatch();}#endregion#region 公有方法/// <summary>/// 吧Task加入到队列里面来管理,既然是个管理器肯定要有个添加task的操作/// </summary>/// <param name="start">多久之后开始执行ms</param>/// <param name="interval">重复时间间隔ms</param>/// <param name="action">任务委托</param>/// <returns>任务id</returns>public static uint AddTimer(uint start, int interval, Action action){AbstractTimeTask task = GetTimeTask(new TimeTask(), start, interval, action);lock (m_queueLock){m_queue.Enqueue(task);}return task.TimeId;}/// <summary>/// 周期性执行/// </summary>public static void Tick(){TimeTaskManager.m_uiTick += (uint)(m_stopWatch.ElapsedMilliseconds);//nityEngine.Debug.Log(TimeTaskManager.m_uiTick);m_stopWatch.Reset();m_stopWatch.Start();while (m_queue.Count != 0){AbstractTimeTask task;lock (m_queueLock){task = m_queue.Peek();//这里注意队列并没有删除元素,只是放回元素,元素还在队列里面}if (TimeTaskManager.m_uiTick < task.NextTick)//如果程序的总时间小于task要执行的时间点,就break点,继续等待{break;}lock (m_queueLock){m_queue.Dequeue();}if (task.Interval > 0)//如果需要重复的话{task.NextTick += (ulong)task.Interval;lock (m_queueLock){m_queue.Enqueue(task);//再次加入队列里面,注意哦,id不变的}task.DoAction();}else {task.DoAction();//执行委托}}}#endregion#region 私有方法private static AbstractTimeTask GetTimeTask(AbstractTimeTask task,uint start,int interval,Action action) {task.Interval = interval;task.TimeId = ++TimeTaskManager.m_uiNextTimeId;task.NextTick = TimeTaskManager.m_uiTick + start;task.Action = action;return task;}#endregion
}

 注意:AddTimer的参数的单位是毫秒,不是秒。

接下来是实验:

首先写个Driver,作为驱动类。

using UnityEngine;
using System.Collections;
#region 模块信息
/*----------------------------------------------------------------
// 模块名:Driver
// 创建者:chen
// 修改者列表:
// 创建日期:2015.11.5
// 模块描述:驱动类
//----------------------------------------------------------------*/
#endregion
public class Driver : MonoBehaviour
{void Start(){TimeTaskManager.AddTimer(5000, 5000, DebugTest);InvokeRepeating("Tick", 0, 0.02f);}void Update(){}void Tick(){TimeTaskManager.Tick();}void DebugTest(){Debug.Log("111");}
}

 创建一个空物体,然后赋予它这个脚本,作为驱动所有程序脚本。

运行,发现程序在5秒之后,每隔5秒打印一个111到控制台。

这个定时类,非常的有用,就比如说网络通信啊,我们可以定时的发送心跳包,还有弹出警告窗口,计时多少秒之后自动关闭等等

 

转载于:https://www.cnblogs.com/CaomaoUnity3d/p/4940655.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

disp语句怎么格式 matlab_Matlab使用技巧总结-1

抽空看了Matlab官方文档&#xff0c;并配合郭老师的课程&#xff0c;把Matlab语言系统梳理了一遍。先上资源&#xff1a;bilibili良心搬运大法&#xff1a;MATLAB_台大郭彦甫-视频教程知乎盐选推荐基础教程&#xff1a;MATLAB 2016_基础实例教程以下记录了一些matlab的技巧。【…

采用CXF+spring+restful创建一个web接口项目

这篇文章是http://blog.csdn.net/zxnlmj/article/details/28880303下面&#xff0c;加入的基础上的restful特征 1、参加restful必jar包裹 jsr311-api-1.0.jarCXF与JAX-RS版本号相应问题,參考自&#xff1a;http://bioubiou.iteye.com/blog/1866871 CXF支持REST风格的Web服务&am…

古风一棵桃花树简笔画_为什么,很多农村家庭的院子里,会喜欢种一棵樱桃树呢?...

小伙伴们去农村的时候&#xff0c;应该都会注意到几乎每家每户的院子里都会种有几棵树吧。如果小伙伴们认真观察的话&#xff0c;你们可以发现很多农村家庭的院子里都有种一两棵樱桃树。那么这是为什么呢&#xff1f;是因为樱桃比较好吃吗&#xff1f;是有这个原因的&#xff0…

Python【02】【基础部分】- B

1、作用域 变量只要在内存存在&#xff0c;就可以被使用 。&#xff08;栈&#xff09; 1 if 1 1: 2 name kim 3 print name 个例&#xff1a;item的值为字典循环后最后一个key的值 1 name {xiaoming:12,xiaohua:15,xiaoli:11} 2 for item in name: 3 print item 4 …

(转)数字格式化函数:Highcharts.numberFormat()

一、函数说明 该函数用于图表中数值的格式化&#xff0c;常见用途有数值精度控制、小数点符、千位符显示控制等。二、函数使用1、函数构造及参数Highcharts.numberFormat (Number number, [Number decimals], [String decimalPoint], [String thousandsSep])参数列表number 需…

cad图层管理插件_设计大神CAD常用七个插件你会用几个?

如果你需要这些CAD插件&#xff0c;可以私信我&#xff0c;小编会及时发给大家​​ 说道CAD插件可能会被人们熟知的也就那几个&#xff0c;可是据统计CAD插件多达上百个&#xff0c;那么在这上百个插件中你又会用几个呢&#xff1f;下面就让我们看看大部分设计师常用的插件有哪…

笔记本显示器仅计算机,别只玩性能 笔记本屏幕怎么进化才靠谱?

1分辨率升级2K不合适一直以来&#xff0c;屏幕显示效果都是笔记本电脑的弱项。近几年笔记本电脑的变化更多是性能以及外观设计的变迁。诸如游戏本以及超极本等产品&#xff0c;在屏幕的优化上&#xff0c;表现都是差强人意。很多人手中的笔记本都是TN屏幕的产品&#xff0c;在显…

计算机专业刚毕业本科生,计算机专业应届本科毕业生自我鉴定

计算机专业应届本科毕业生自我鉴定四年的大学生活是我人生这条线上的一小段&#xff0c;是闪闪发光的一段&#xff0c;它包含了汗水和收获&#xff0c;为我划平人生的线起着至关重要的作用。四年大学生活已接近尾声&#xff0c;感觉非常有必要总结一下大学四年的得失&#xff0…

佳能c3320怎么设置接收方_入门级单反相机佳能800D是否值得买?在我看来价格决定一切...

佳能入门级单反相机800D是否值得买看了就清楚旺灵龙如果你是一位刚刚准备购买数码单反相机的入门小白&#xff0c;佳能最新的EOS 800D的肯定是你现在最容易拿来对比的选择。新相机在性能与操作便利性方面的良好结合&#xff0c;无疑将是入门级单反性价比最高的一款机型。佳能(C…

stm8时钟源

下面4种时钟源可用做主时钟&#xff1a; 1-24MHz高速外部晶体振荡器(HSE)最大24MHz高速外部时钟信号(HSE user-ext)16MHz高速内部RC振荡器(HSI)128KHz低速内部RC(LSI)各个时钟源可单独打开或关闭&#xff0c;从而优化功耗。 (一)HSE 高速外部时钟信号可由下面两个时钟源产生&am…

nexus 仓库类型_Maven私服Nexus的搭建

私服存在的合理性Maven中的依赖是从服务器仓库中下载的&#xff0c;Maven的仓库只有两大类&#xff1a;本地仓库远程仓库&#xff0c;其中在远程仓库中又分成了3种&#xff1a;中央仓库 、私服、其它公共库。Maven用户直接连接远程仓库下载构件的做法是Maven不建议使用的&#…

ae中心点重置工具_AE中图形绘制的6大技巧,简单易操作

AE中的图形系统和文字系统很相似&#xff0c;都有自己相对独立的一套基础动画系统。当我们打开AE软件&#xff0c;面对空白的面板&#xff0c;如何通过一步步的操作填充画面&#xff0c;做出酷炫的效果&#xff0c;这其中图形占据很大的比重&#xff0c;更不用说流行的MG动画&a…

Mac安装软件报“打不开。。。,因为它来自身份不明的开发者”的解决办法

问题描述 在Mac上安装git&#xff0c;双击pkg进行安装&#xff0c;报如下图错误&#xff1a; 解决办法 不要双击pkg文件&#xff0c;改成选中文件之后&#xff0c;鼠标右键&#xff0c;选择“打开方式->安装器&#xff08;默认&#xff09;”&#xff0c;即可继续安装。 转载…

模型预测控制c语言程序_搭建第一个程序控制电路LED灯,体会C语言的魅力

学习C语言&#xff0c;先从读程序开始&#xff01;这一点是过来人的经验之谈。本文建议大家选择一款图形编程软件&#xff0c;本文选择了Mixly。一、首先&#xff0c;介绍一下arduino UNO控制器内部电压的问题。v 高电平(5V)&#xff1a;对应数值是1&#xff0c;输入状态3.5V-5…

s丅7318是啥芯片_透彻解析LED驱动芯片HT1632C指令集与驱动编程

HT1632C是一款很常用的LED(数码管或点阵)驱动芯片&#xff0c;虽然官方已经宣布该芯片明年(2021年)即将寿终正寝(停产)&#xff0c;但是相同厂家生产的同系列芯片的控制方式通常是相同的(事实上&#xff0c;大多数LED驱动芯片差别也不大)&#xff0c;所以了解HT1632C的控制原理…

服务器显示不明用户远程过,服务器显示不明用户远程过

服务器显示不明用户远程过 内容精选换一换Windows操作系统云服务器蓝屏&#xff0c;如图1所示。使用了来源不明的第三方软件。CPU占用过高导致。因为误操作或者病毒引起的系统文件、注册表损坏。操作系统在蓝屏的情况下&#xff0c;会显示对应的bugcheck code以及可能的导致蓝屏…

微信小程序定义全局变量_微信小程序第二天学习内容分享

微信小程序的生命周期文件的配置在app.js文件中&#xff1b;方法&#xff1a;onLaunch,onShow,onHideapi链接&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/reference/api/App.html#onHideonError,当前也可以自定义&#xff0c;用console测试事件的执行情况&a…

java环境配置—配置Tomcat8环境

先安装JDK&#xff0c;配置好jdk环境后再配置Tomcat 8配置环境变量&#xff1a;TOMCAT_HOME&#xff1a;D:\Program Files\apache-tomcat-8.0.28  CATALINA_HOME:D:\Program Files\apache-tomcat-8.0.28  CATALINA_BASE:D:\Program Files\apache-tomcat-8.0.28修改CLASSPAT…

ios13苹方字体ttf_字体 | iOS1013 SF Compact Rounded 英文 By alex

最近沉迷游戏&#xff0c;差点忘记了这个英文。嗨呀&#xff0c;问就是在玩了&#xff0c;啊不&#xff0c;在做了。这个英文来自推特alexman&#xff0c;原版包含100和85大小&#xff0c;本次分享新增到了100-60&#xff0c;每5%一个大小。gzh分享已经获得alex授权&#xff0c…

10双屏鼠标过不去_灵耀X2 Duo双屏笔记本是怎样“炼”成的?对话华硕笔记本设计团队...

2020年的CES上&#xff0c;华硕推出了一款灵耀X2 Duo笔记本&#xff0c;灵耀X2 Duo采用了和灵耀X2 Pro相同的屏幕技术&#xff0c;C面同样采用了一块ScreenPad Plus副屏&#xff0c;机身也更轻更薄。如今灵耀X2 Duo的处理器升级至英特尔第十代酷睿&#xff0c;正在参与“618”大…