Unity 模拟协程实现计时器功能
众所周知,在Unity里面开启协程会有消耗,有时候就算我们只需要用到一个简单的计时器,必须开一个协程或者自己写一个计时器。这里提供了一个通用的计时器类,里面还实现了内存池管理,使用完的计时器回收备用。
使用方法:只需负责调用即可,内部会自动回收。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class GlobalTimer : MonoBehaviour
{
private static GlobalTimer instance;
public static GlobalTimer Instance
{
get
{
if (!instance)
{
instance = GameObject.FindObjectOfType();
}
if (!instance)
{
GameObject obj = new GameObject(typeof(GlobalTimer).ToString());
instance = obj.AddComponent();
}
return instance;
}
}
//正在使用的TimerData
private List mUseTimerDatas = new List();
//空闲的TimerData
private List mNotUseTimerDatas = new List();
//尝试从空闲池中取一个TimerData
private TimerData GetTimerData(bool isAdd = true)
{
TimerData data = null;
if (mNotUseTimerDatas.Count <= 0)
{
data = new TimerData();
}
else
{
data = mNotUseTimerDatas[0];
mNotUseTimerDatas.RemoveAt(0);
}
mUseTimerDatas.Add(data);
return data;
}
//创建一个计时器
public TimerData AddTimer(float _duration, Action endCallBack, bool _isIgnoreTime = false)
{
TimerData data = GetTimerData();
data.Init(_duration, endCallBack, _isIgnoreTime);
return data;
}
//创建一个重复型计时器
public TimerData AddIntervalTimer(float _duration, float _interval, Action _endCallBack, Action _intervalCallBack, bool _isIgnoreTime = false)
{
TimerData data = GetTimerData();
data.Init(_duration, _endCallBack, _isIgnoreTime, _interval, _intervalCallBack);
return data;
}
protected void Clear(TimerData data)
{
if (mUseTimerDatas.Remove(data))
{
mNotUseTimerDatas.Add(data);
}
else
{
Debug.LogWarning("GlobalTimer not find TimerData");
}
}
#region 测试代码
void Start()
{
TimerData td1 = GlobalTimer.Instance.AddTimer(5,
() =>
{
Debug.Log("5秒后调用该方法1");
});
TimerData td2 = GlobalTimer.Instance.AddIntervalTimer(5, 1,
() =>
{
Debug.Log("5秒后调用该方法2");
},
(float remainTime) =>
{
Debug.Log("每一秒调用执行此处:剩余时间" + remainTime);
}
);
}
#endregion
void Update()
{
for (int i = 0; i < mUseTimerDatas.Count; ++i)
{
if (!mUseTimerDatas[i].Update())
{
//没更新成功,mUseTimerDatas长度减1,所以需要--i
--i;
}
}
}
public class TimerData
{
//持续时间
private float mDuration;
//重复间隔
private float mInterval;
//结束回调
private Action mEndCallBack;
//每次重复回调
private Action mIntervalCallBack;
//是否忽略时间
private bool isIgnoreTime;
//计时器
private float mRunTime;
//间隔计时器
private float mRunIntervalTime;
//初始化
public void Init(float _duration, Action _endCallBack, bool _isIgnoreTime = false, float _interval = -1f, Action _intervalCallBack = null)
{
mDuration = _duration;
mInterval = _interval;
mEndCallBack = _endCallBack;
mIntervalCallBack = _intervalCallBack;
isIgnoreTime = _isIgnoreTime;
mRunTime = 0;
mRunIntervalTime = 0;
}
//更新
public bool Update()
{
float deltaTime = isIgnoreTime ? Time.unscaledDeltaTime : Time.deltaTime;
mRunTime += deltaTime;
mRunIntervalTime += deltaTime;
if (mIntervalCallBack != null)
{
if (mRunIntervalTime >= mInterval)
{
mRunIntervalTime -= mInterval;
mIntervalCallBack(mDuration - mRunTime);
}
}
if (mRunTime >= mDuration)
{
if (mEndCallBack != null)
{
mEndCallBack();
}
Clear();
return false;
}
return true;
}
public void Clear()
{
instance.Clear(this);
}
public void AddEndCallBack(Action _endCallBack)
{
mEndCallBack += _endCallBack;
}
}
}
---------------------
作者:大城市下的蚂蚁
来源:CSDN
原文:https://blog.csdn.net/z625309640/article/details/78105626
版权声明:本文为博主原创文章,转载请附上博文链接!
- 用 PHP 的方式实现的各类算法合集
- Nginx 反向代理解决前后端联调跨域问题
- JavaScript对象length
- Go1.8.4和Go1.9.1版本发布
- Javascript数组操作
- Tensorflow官方语音识别入门教程 | 附Google新语音指令数据集
- jQuery VS JavaScript原生API
- 居于H5的多文件、大文件、多线程上传解决方案
- 抛弃websocket,前端直接打通信道,webRTC搭建音视频聊天
- Golang学习-第三篇 认识Web框架
- Golang学习-第二篇 搭建一个简单的Go Web服务器
- 数据说话:Go语言的Switch和Map性能实测
- Dora.Interception, 为.NET Core度身打造的AOP框架[4]:演示几个典型应用
- Dora.Interception, 为.NET Core度身打造的AOP框架[3]:Interceptor的注册
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法