Unity3D延迟回调的封装
最近,整理项目框架逻辑时,无意中翻到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延迟回调的封装的更多相关文章
- Vue.nextTick DOM 更新循环结束之后执行延迟回调
在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 简单来说,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统 ...
- C#将C++动态库的回调函数封装成事件
关于C#调用C++动态库的文章很多,调用动态库中回调函数的方法也不在少数.但大多数调用回调函数的方法依然保留了C++的语法特点. 比如有一段C++的回调函数代码,为了表达它的意思,我把注释也粘贴了进来 ...
- c++ 回调函数封装
std::function<void(int a,int b)> ha; //函数封装 当成参数用callback std::bind(&fun1,this,std::plac ...
- unity3d 延迟运行脚本语句
在Unity3D中.有yield语句它负责延迟操作,yield return WaitForSeconds(3.0); //等待 3 秒 查看unity3d脚本手冊,使用方法须要在对应的格式. 以下代 ...
- Unity3D 动画回调方法
最近发现很多coder.在用Unity开发游戏的时候都需要一个需求就是..动画播到某一帧就要干什么事情.而且希望能得到回调. 在unity里面的window菜单有个.Animation工具.打开它.然 ...
- PCL中将回调函数封装到类中
这是类中的声明 private://点云回调函数 NuClearTask_MyPointCloudHandle //点云选择 static void ps_callback(const pcl::vi ...
- unity3d 延迟处理方法
Invoke("方法名", 多少秒后执行); InvokeRepeating("方法名", 多少秒后执行,开始执行后隔多长时间再次执行一次); CancelIn ...
- Unity3D手游开发实践
<腾讯桌球:客户端总结> 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: 架构设计 原生插件/ ...
- Unity3d 与 Objective-C 数据交互,持续更新中
Unity 3D是用于3D游戏编程的语言,它是一个用C\C++编写的强大的库.而在游戏中经常要接入用OC编写的SDK,这就涉及到了Unity3d 和 OC之间的数据交互.XCode是完成兼容C语言的. ...
随机推荐
- C#中的委托用法
当一个函数有返回值的时候用,用Func委托方法. 例如: static int sum(int x) { return x+x; } Func<int> a = sum; 当一个函数没有返 ...
- 头文件的宏定义#ifndef测试
一.入题 在头文件的书写中,都加入了如下内容: #ifndef __头文件名_H #define __头文件名_H #endif 曾经在书中看到的解释是“防止重复定义”,今天突然想到为什么是这样的解释 ...
- Keil的c语言编译器
我曾经通过查看反汇编代码对KEILC编译器进行了测试,大概有这么一下内容,也得出一些结论. (1)全局变量:如果程序中定义了全局变量,而且初始值不是0.此时,在程序调到main()函数执行前,除了要进 ...
- Ionic简介和环境安装
什么是Ionic Ionic是一个用来开发混合手机应用的,开源的,免费的代码库.可以优化html.css和js的性能,构建高效的应用程序,而且还可以用于构建Sass和AngularJS的优化.ioni ...
- qt5 基础知识
QWidget wQLineEdit edit; edit.show(); //如果没有这句,编辑框edit将会显示在父窗口的左上角edit.setParent(&w); //以w为父窗口并显 ...
- [wikioi]没有上司的舞会
树形DP.用F[k][0]和F[k][1]表示某节点不选和选了之后子树的最大值.那么:f[i][0]=sigma(max(f[k][0],f[k][1]))f[i][1]=sigma(f[k][0]) ...
- linux使用ps1设置命令行提示符
要自定义命令行提示,需要ps1来设置.完成自定义需要以下几个步骤: 1.编辑~/.bashrc文件 vi ~/.bashrc 2.在.bashrc文件中添加以下一行自定义内容 export PS1=& ...
- 【Xamarin挖墙脚系列:在VMware11中安装Mac10.11 EI Captain后的vmware tools】
原文:[Xamarin挖墙脚系列:在VMware11中安装Mac10.11 EI Captain后的vmware tools] 如何安装 darwin.iso,百度去吧. 关键是对应版本的darwin ...
- Perl脚本学习经验(三)--Perl中ftp的使用
使用use Net::FTP;Demo: my $Server = '192.168.1.1'; my $User = 'admin'; my $Password = 'admin' ...
- SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '/tmp/ClientActionTrack2015112511.txt' 不堵塞事务
mysql> insert into ClientActionTrack20151125(clientSn,ip,url,httpMethod,requestParams,requestHead ...