最近,整理项目框架逻辑时,无意中翻到n年前封装的延迟回调管理器,就拎出来说道说道:

  先说一下系统提供的几种常用的延迟回调方式:

1)Invoke(Invoke、CancelInvoke):首先需要继承自MonoBehaviour,其次使用的是函数名作为参数调用,比较麻烦,容易出错(运行时才会审查,编译检查不到);
2)Coroutine(StartCoroutine、StopCoroutine):仍然继承自MonoBehaviour,调用时可以使用函数名,也可以直接传入委托,效率上不高,每次调用都会牵扯到额外的堆内存分配,并且所挂载的游戏对象状态不能被打断,否则执行也会被打断;
3、Update:依赖MonoBehaviour,每次调用需要单独申请变量,重写逻辑,也会因状态打断而停止执行;
在不使用插件的情况下,索性进行一些封装,综合各自的优点,去其糟粕:

public class InvokeManager
{
private InvokeManager() //泛型单件
{
timeDelayLst = new List<float>();
timeStateLst = new List<bool>();
callbackDelayLst = new List<System.Action>();
} private IList<float> timeDelayLst;
private IList<bool> timeStateLst;
private IList<System.Action> callbackDelayLst; public void Invoke(float _timeDelay, System.Action _callback)
{
timeDelayLst.Add(_timeDelay);
timeStateLst.Add(false);
callbackDelayLst.Add(_callback);
}
public int CancelInvoke(System.Action _callback, bool _cancelAll = false) //false:仅取消最后注册的(和延迟时间无关);返回int型,可以根据剩余的次数立即执行未执行的回调函数
{
int tCount = ;
for(int i = callbackDelayLst.Count - ; i >= ; i--)
{
if(callbackDelayLst[i].Equals(_callback))
{
tCount++;
timeDelayLst.RemoveAt(i);
timeStateLst.RemoveAt(i);
callbackDelayLst.RemoveAt(i);
if(!_cancelAll)
{
return tCount;
}
}
}
return tCount;
}
public void ClearInvoke()
{
timeDelayLst.Clear();
timeStateLst.Clear();
callbackDelayLst.Clear();
}
public void TickUpdate(float _deltaTime)
{
filtTick(_deltaTime);
for(int i = timeStateLst.Count - ; i >= ; i--)
{
timeStateLst[i] = false;
}
}
  private void filtTick(float _deltaTime)
  {
    for(int i = timeDelayLst.Count - ; i >= ; i--)
    {
      if(timeStateLst.Count > i && !timeStateLst[i])
      {
        timeDelayLst[i] -= _deltaTime;
        timeStateLst[i] = true;
        if(timeDelayLst[i] <= )
        {
          var tCallback = callbackDelayLst[i];//从后向前遍历:删除最后注册(和延迟时间无关)的事件回调(可以自行扩展根据延迟时间进行删除)
          timeDelayLst.RemoveAt(i);
          timeStateLst.RemoveAt(i);
          callbackDelayLst.RemoveAt(i);           tCallback();
          filtTick(_deltaTime);
        }
      }
    }
  }
}

封装之后仅需要在主函数逻辑中进行驱动计时,之后就可以根据需要方便的延迟及取消延迟了。(PS:因为只是简单的封装,因此还有以下缺点:1)递归回调的问题;2)无法取消匿名的回调函数。)
当然,也有一些比较方便使用的插件,这个可以根据需要自行研究了,eg:Vision Timer等,DoTween等也有提供接口功能。

Unity3D延迟回调的封装的更多相关文章

  1. Vue.nextTick DOM 更新循环结束之后执行延迟回调

    在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 简单来说,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统 ...

  2. C#将C++动态库的回调函数封装成事件

    关于C#调用C++动态库的文章很多,调用动态库中回调函数的方法也不在少数.但大多数调用回调函数的方法依然保留了C++的语法特点. 比如有一段C++的回调函数代码,为了表达它的意思,我把注释也粘贴了进来 ...

  3. c++ 回调函数封装

    std::function<void(int a,int b)> ha; //函数封装  当成参数用callback  std::bind(&fun1,this,std::plac ...

  4. unity3d 延迟运行脚本语句

    在Unity3D中.有yield语句它负责延迟操作,yield return WaitForSeconds(3.0); //等待 3 秒 查看unity3d脚本手冊,使用方法须要在对应的格式. 以下代 ...

  5. Unity3D 动画回调方法

    最近发现很多coder.在用Unity开发游戏的时候都需要一个需求就是..动画播到某一帧就要干什么事情.而且希望能得到回调. 在unity里面的window菜单有个.Animation工具.打开它.然 ...

  6. PCL中将回调函数封装到类中

    这是类中的声明 private://点云回调函数 NuClearTask_MyPointCloudHandle //点云选择 static void ps_callback(const pcl::vi ...

  7. unity3d 延迟处理方法

    Invoke("方法名", 多少秒后执行); InvokeRepeating("方法名", 多少秒后执行,开始执行后隔多长时间再次执行一次); CancelIn ...

  8. Unity3D手游开发实践

    <腾讯桌球:客户端总结> 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: 架构设计 原生插件/ ...

  9. Unity3d 与 Objective-C 数据交互,持续更新中

    Unity 3D是用于3D游戏编程的语言,它是一个用C\C++编写的强大的库.而在游戏中经常要接入用OC编写的SDK,这就涉及到了Unity3d 和 OC之间的数据交互.XCode是完成兼容C语言的. ...

随机推荐

  1. Activity组件的UI实现

    Activity组件的UI实现需要与WindowManagerService服务和SurfaceFlinger服务进行交互 1. Activity组件在启动完成后,会通过一个类型为Session的Bi ...

  2. 配置Apache服务器 数据库mySQL

    Mac 配置  apache   php 详细解说 一.开启apache 并切改变引导 1.打开终端  输入:sudo apachectl start    回车,关闭终端 2.打开浏览器,地址栏输入 ...

  3. 数据采集服务提供商,ip提供商 里面有些不错的基础数据

    http://user.qzone.qq.com/1649677458 这家公司的爬虫应该挺牛的 !@#!#!~#¥¥¥@@http://www.site-digger.com/

  4. 【技术贴】破解Myeclipse10.7

    程序用的是http://www.cr173.com/soft/58306.html这个破解程序,是英文版的中文版.使用起来非常爽,看下面 使用期间关掉Myeclipse 期间的第三步,点击激活,此时会 ...

  5. OA学习笔记-007-Dao层设计

    一. User, UserDao save(User user), update(), delete(), find(), ...Role, RoleDao save(Role role), upda ...

  6. 周鸿祎——不要抱着打工心态去工作,而是把工作当创业(附读书笔记) good

    360周鸿祎反而最为开明,他说“不要抱着打工心态去工作,而是把工作当创业”,就像是,鼓励你拿着公司的工资,锻炼自己的能力,为自己以后创业积累资源和人脉(读书笔记:真是天底下最好的机会,天底下没有比工作 ...

  7. relink:在Linux/UNIX平台上relink Oracle软件(转)

    当操作系统升级后.操作系统打完补丁后.安装完Oracle补丁之后和relink过程中出现问题时,都会用到relink方法来保证Oracle软件的正常使用.本文介绍一下relink方法的使用.   1. ...

  8. OSS研究

    在以前没有毕业之前,做过了一个了播放器,其实就是mplayer的二次开发. 如果在这个播放器之上,加个oss作声音输入,那不就可以做个卡拉OK啦? 1.OSS的定义 OSS(Open Sound Sy ...

  9. POJ_3685_Matrix_(二分,查找第k大的值)

    描述 http://poj.org/problem?id=3685 一个n*n的矩阵,(i,j)的值为i*i+100000*i+j*j-100000*j+i*j,求第m小的值. Matrix Time ...

  10. Java序列化技术

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化? Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象 ...