Unity常用协程功能封装
# 1.前言
unity开发过程中,经常用到一些特定的协程功能,比如延时触发、等待触发、重复操作等。unity自带Invoke以及InvokeRepeating方法,但这些方法均采用反射机制,性能消耗,而且代码混淆时极其容易出错。所以再次对这些功能做以下简单封装。方便后续使用。
# 2.CoroutineJobCenter
CoroutineJobCenter封装了需要的基本方法。
## 2.1 延时触发
延时一定事件触发。
```csharp
public IEnumerator StartJobDelayed(float delayedTime, Action action)
{
yield return new WaitForSeconds(delayedTime);
if (action != null)
{
action();
}
}
public IEnumerator StartJobDelayed<T>(float delayedTime, Action<T> action, T t)
{
yield return new WaitForSeconds(delayedTime);
if (action != null)
{
action(t);
}
}
```
## 2.2 等待触发
等待某一条件返回true时触发,采用unity自带的WaitUntil类。
```csharp
public IEnumerator StartJobUntil(Func<bool> funtion, Action action)
{
yield return new WaitUntil(funtion);
if (action != null)
{
action();
}
}
public IEnumerator StartJobUntil<T>(Func<bool> funtion, Action<T> action, T t)
{
yield return new WaitUntil(funtion);
if (action != null)
{
action(t);
}
}
```
## 2.3 重复触发
### 2.3.1 每隔一帧触发,并规定触发次数。
```csharp
public IEnumerator RepeatJobPerFrame(int count, Action action)
{
for (int i = 0; i < count; i++)
{
yield return null;
if (action != null)
{
action();
}
}
}
public IEnumerator RepeatJobPerFrame<T>(int count, Action<T> action, T t)
{
for (int i = 0; i < count; i++)
{
yield return null;
if (action != null)
{
action(t);
}
}
}
```
### 2.3.2 每隔固定时间触发,并规定触发次数。
```csharp
public IEnumerator RepeatJobPerTimespan(int count, float interval, Action action)
{
yield return new RepeatJobPerTimespan(action, count, interval);
}
```
```csharp
public class RepeatJobPerTimespan : CustomYieldInstruction
{
private Action action;
private int count;
private int repeatCount;
private float timeSpan;
private float startedTime;
public override bool keepWaiting
{
get
{
if (repeatCount >= count)
{
return false;
}
else if(Time.time - startedTime >= timeSpan)
{
startedTime = Time.time;
repeatCount++;
if (action != null)
{
action();
}
}
return true;
}
}
public RepeatJobPerTimespan(Action action, int count, float timeSpan)
{
this.action = action;
this.count = count;
this.timeSpan = timeSpan;
startedTime = Time.time;
repeatCount = 0;
}
}
```
### 2.3.3 规定时间内,间隔触发
**注意:**
由于间隔多长时间 触发的时间间隔并不精确,所以会影响触发次数。比如每隔两秒执行一次,一共执行六秒。则不会执行三次,因为每次等待两秒,根据判断肯定会超过两秒。所以不会有第三次执行。此时可以适当放宽总时间或者减小时间间隔。
```csharp
public IEnumerator RepeatJobInCertainTimeSpan(float timeSpan, float interval, Action action)
{
yield return new RepeatJobInCertainTimespan(action, interval, timeSpan);
}
```
```csharp
public class RepeatJobInCertainTimespan : CustomYieldInstruction
{
private Action action;
private float startTime;
private float lastJobTime;
private float interval;
private float timeSpan;
public override bool keepWaiting
{
get
{
if (Time.time - startTime > timeSpan)
{
return false;
}
else if (Time.time - lastJobTime >= interval)
{
lastJobTime = Time.time;
if (action != null)
{
action();
}
}
return true;
}
}
public RepeatJobInCertainTimespan(Action action, float interval, float timeSpan)
{
this.action = action;
this.interval = interval;
this.timeSpan = timeSpan;
this.startTime = Time.time;
this.lastJobTime = Time.time;
}
}
```
## 2.4 规定的时间内等待触发
这是一个比较常用的方法,比如超时等待。即如果在规定的时间内完成或者超过规定的时间,则进行下一步处理。
```csharp
public IEnumerator WaitUntilInCertainTimespan(float timeSpan, Func<bool> function, Action action)
{
yield return new WaitUntilInCertaiTime(function, timeSpan);
if (action != null)
{
action();
}
}
```
```csharp
public class WaitUntilInCertaiTime : CustomYieldInstruction
{
private Func<bool> function;
private float timeSpan;
private float startTime;
public override bool keepWaiting
{
get
{
if (function() || Time.time - startTime > timeSpan)
{
return false;
}
return true;
}
}
public WaitUntilInCertaiTime(Func<bool> function,float timeSpan)
{
this.function = function;
this.timeSpan = timeSpan;
startTime = Time.time;
}
}
```
# 3.应用
```csharp
using CoroutineJob;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CorountineJobTest : MonoBehaviour
{
public Button button;
private bool flag = false;
private void Start()
{
button.onClick.AddListener(OnStateChange);
//StartCoroutine(CoroutineJobCenter.Instance.StartJobUntil(() => { return flag; }, () =>
//{
// Debug.Log("StartJobUntil");
//}));
//StartCoroutine(CoroutineJobCenter.Instance.RepeatJobPerTimespan(5, 2, () =>
//{
// Debug.Log("RepeatJobPerTimespan");
//}));
//StartCoroutine(CoroutineJobCenter.Instance.RepeatJobInCertainTimeSpan(6, 1.8f, () =>
//{
// Debug.Log("RepeatJobInCertainTimeSpan");
//}));
StartCoroutine(CoroutineJobCenter.Instance.WaitUntilInCertainTimespan(6, () => { return flag; }, () =>
{
Debug.Log("RepeatJobInCertainTimeSpan");
}));
}
void OnStateChange()
{
flag = true;
}
}
```
Unity常用协程功能封装的更多相关文章
- c#基类 常用数据验证的封装,数字,字符,邮箱的验证
#region 常用数据验证的封装,数字字符的验证 /// <summary> /// 常用数据验证的封装,数字字符的验证 /// </summa ...
- 游戏编程之Unity常用脚本类的继承关系
前言学习Unity开发引擎的初学者会接触大量的脚本类,而这些类之间的关系往往容易被忽略.本文对Unity引擎开发中的一些常用类及其关系进行了简单的归纳总结. 博文首发地址:http://tieba.b ...
- Unity常用常找(二)
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/51315050 作者:car ...
- unity常用小知识点
感觉自己抑郁变得更严重了,超级敏感,经常想崩溃大哭,睡眠超差,实在不想药物治疗,多看看书,多约约朋友,多出去走走. 来几句鸡汤吧,人一定要活得明白一点,任何关系都不要不清不楚,说不定最后受伤的就是自个 ...
- 关于Unity中协程、多线程、线程锁、www网络类的使用
协程 我们要下载一张图片,加载一个资源,这个时候一定不是一下子就加载好的,或者说我们不一定要等它下载好了才进行其他操作,如果那样的话我就就卡在了下载图片那个地方,傻住了.我们希望我们只要一启动加载的命 ...
- Unity(四)IocContainer 封装类库
首先要在项目中安装Unity,通过NuGet搜索Unity. 1.定义接口 IDependencyResolver using System; using System.Collections.Gen ...
- [Unity菜鸟] 协程Coroutine
1.协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态. unity中StartCoroutine()就是协程,协程实际上是在一个线程中, ...
- VSPackge插件系列:常用IDE功能的封装
继上一篇VSPackge插件系列简单介绍如何正确的获取DTE之后,就一直没发VSPackge插件系列的文章了,最近同事也想了解如何在代码中与VS交互,特发一篇文章示例一些简单功能是如何调用,也以备以后 ...
- MYSQL常用操作函数的封装
1.mysql常用函数封装文件:mysql.func.php <?php /** * 连接MYSQL函数 * @param string $host * @param string $usern ...
随机推荐
- js---电商中常见的放大镜效果
js中的放大镜效果 在电商中,放大镜效果是很常见的,如下图所示: 当鼠标悬浮时,遮罩所在区域在右侧进行放大. 在动手写之前,我们要先理清思路,分析需求,所需知识点,再将每一块进行组装,最后进行功能的完 ...
- CDH 5.9.3 集群配置
-----------------------------------------集群规划------------------------------------------ hostname ip ...
- tomcat配置目录及安装说明
1.升级jdk版本 java -version 查看当前java版本 上传最新版jdk tar xf jdk-8u191-linux-x64.tar.gz 解压jdk到当前下 mv jdk1.8.0_ ...
- Scala 数组和List
Scala 数组和List: import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.Buffer ob ...
- AVL平衡二叉查找树
二叉排序树: 定义 二叉排序树,又叫二叉查找树,它或者是一棵空树:或者是具有以下性质的二叉树: 1. 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值: 2. 若它的右子树不空,则右子树上 ...
- Windows 8.1硬盘安装Ubuntu 14.04双系统参考教程及多硬盘注意事项
本文来自:http://www.linuxidc.com/Linux/2015-08/122140.htm,此处仅做收藏. Windows 8.1硬盘安装Ubuntu 14.04双系统参考教程及多硬盘 ...
- C# 获取pdf长宽,反推pdf图纸类型
业务需求:读取pdf每页的长宽,然后根据国际标准,反推出pdf图纸类型 第一步:下载类库,并引入到项目中 链接:https://pan.baidu.com/s/1ud4-xhfDvi9OKolEBPw ...
- css中em单位详解,说明
em详解 em可以理解成“倍”. em会以父级元素中所设置的字体像素值为基准值进行成倍放大: 字体大小=(父级元素中的字体像素 * em的值) 例: 网页部分代码如下: 1.我现在没有在父级 ...
- c语言中double类型数据的输入和输出
double a;scanf("%f",&a); //应用scanf("%lf",&a);执行上面语句时,发现double类型的输入不能使用 ...
- 使用canvas生成含有微信头像的邀请海报没有微信头像
最近做了一个微信内访问的H5页面,长按分享图片发送朋友邀请的海报,网上搜索资料,得出解决思路,用canvas将页面绘制生成图片, 问题:canvas 图片跨域. 解决过程(填坑历程): 1.从网上存在 ...