Unity协程(Coroutine)管理类——TaskManager工具分享
Unity协程(Coroutine)管理类——TaskManager工具分享
By D.S.Qiu
尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com
在分享vp_Timer 中提到,没有继承的MonoBehaviour,没有Update,InVoke 和StartCoroutine的机制,vp_Timer就是提供了InVoke的机制,而且还可以统一管理。本篇D.S.Qiu要分享的TaskManager就是一个协程 管理类。 TaskManager —— Unity3D Managed Coroutines with Start, Stop, Resume ,看着就觉得很强大,当然是对于我这种对协程理解不深的来说。下面贴出 The Motivation of the author:
/// The motivation for this is twofold:
///
/// 1. The existing coroutine API provides no means of stopping specific
/// coroutines; StopCoroutine only takes a string argument, and it stops
/// all coroutines started with that same string; there is no way to stop
/// coroutines which were started directly from an enumerator. This is
/// not robust enough and is also probably pretty inefficient.
///
/// 2. StartCoroutine and friends are MonoBehaviour methods. This means
/// that in order to start a coroutine, a user typically must have some
/// component reference handy. There are legitimate cases where such a
/// constraint is inconvenient. This implementation hides that
/// constraint from the user.
代码很简单,但却很解渴,Unity官方只听过了StopCoroutine(string methodName)或StopAllCoroutine() 这两个停止方法,从api就会觉得Unity的整体方法论还不完善,所以才会觉得TaskManager的难能可贵。由于源码简单,就不做解释了,See source for document :
/// Simple, really. There is no need to initialize or even refer to TaskManager.
/// When the first Task is created in an application, a "TaskManager" GameObject
/// will automatically be added to the scene root with the TaskManager component
/// attached. This component will be responsible for dispatching all coroutines
/// behind the scenes.
///
/// Task also provides an event that is triggered when the coroutine exits. using UnityEngine;
using System.Collections; /// A Task object represents a coroutine. Tasks can be started, paused, and stopped.
/// It is an error to attempt to start a task that has been stopped or which has
/// naturally terminated.
public class Task
{
/// Returns true if and only if the coroutine is running. Paused tasks
/// are considered to be running.
public bool Running {
get {
return task.Running;
}
} /// Returns true if and only if the coroutine is currently paused.
public bool Paused {
get {
return task.Paused;
}
} /// Delegate for termination subscribers. manual is true if and only if
/// the coroutine was stopped with an explicit call to Stop().
public delegate void FinishedHandler(bool manual); /// Termination event. Triggered when the coroutine completes execution.
public event FinishedHandler Finished; /// Creates a new Task object for the given coroutine.
///
/// If autoStart is true (default) the task is automatically started
/// upon construction.
public Task(IEnumerator c, bool autoStart = true)
{
task = TaskManager.CreateTask(c);
task.Finished += TaskFinished;
if(autoStart)
Start();
} /// Begins execution of the coroutine
public void Start()
{
task.Start();
} /// Discontinues execution of the coroutine at its next yield.
public void Stop()
{
task.Stop();
} public void Pause()
{
task.Pause();
} public void Unpause()
{
task.Unpause();
} void TaskFinished(bool manual)
{
FinishedHandler handler = Finished;
if(handler != null)
handler(manual);
} TaskManager.TaskState task;
} class TaskManager : MonoBehaviour
{
public class TaskState
{
public bool Running {
get {
return running;
}
} public bool Paused {
get {
return paused;
}
} public delegate void FinishedHandler(bool manual);
public event FinishedHandler Finished; IEnumerator coroutine;
bool running;
bool paused;
bool stopped; public TaskState(IEnumerator c)
{
coroutine = c;
} public void Pause()
{
paused = true;
} public void Unpause()
{
paused = false;
} public void Start()
{
running = true;
singleton.StartCoroutine(CallWrapper());
} public void Stop()
{
stopped = true;
running = false;
} IEnumerator CallWrapper()
{
yield return null;
IEnumerator e = coroutine;
while(running) {
if(paused)
yield return null;
else {
if(e != null && e.MoveNext()) {
yield return e.Current;
}
else {
running = false;
}
}
} FinishedHandler handler = Finished;
if(handler != null)
handler(stopped);
}
} static TaskManager singleton; public static TaskState CreateTask(IEnumerator coroutine)
{
if(singleton == null) {
GameObject go = new GameObject("TaskManager");
singleton = go.AddComponent<TaskManager>();
}
return new TaskState(coroutine);
}
}
/// Example usage:
///
/// ----------------------------------------------------------------------------
/// IEnumerator MyAwesomeTask()
/// {
/// while(true) {
/// Debug.Log("Logcat iz in ur consolez, spammin u wif messagez.");
/// yield return null;
//// }
/// }
///
/// IEnumerator TaskKiller(float delay, Task t)
/// {
/// yield return new WaitForSeconds(delay);
/// t.Stop();
/// }
///
/// void SomeCodeThatCouldBeAnywhereInTheUniverse()
/// {
/// Task spam = new Task(MyAwesomeTask());
/// new Task(TaskKiller(5, spam));
/// }
/// ----------------------------------------------------------------------------
小结:
本文主要是分享我的收藏的一些“干货”,TaskManager 和 vp_Timer 在项目中发挥了很大的作用,D.S.Qiu 一再觉得强大的东西不都是复杂的,能够使用最简单的本质方法解决问题才是代码设计的追求。 文末附上了相关的链接以及TaskManager的代码。
如果您对D.S.Qiu有任何建议或意见可以在文章后面评论,或者发邮件(gd.s.qiu@gmail.com)交流,您的鼓励和支持是我前进的动力,希望能有更多更好的分享。
转载请在文首注明出处:http://dsqiu.iteye.com/blog/2022992
更多精彩请关注D.S.Qiu的博客和微博(ID:静水逐风)
Unity协程(Coroutine)管理类——TaskManager工具分享的更多相关文章
- Unity协程Coroutine使用总结和一些坑
原文摘自 Unity协程Coroutine使用总结和一些坑 MonoBehavior关于协程提供了下面几个接口: 可以使用函数或者函数名字符串来启动一个协程,同时可以用函数,函数名字符串,和Corou ...
- unity协程coroutine浅析
转载请标明出处:http://www.cnblogs.com/zblade/ 一.序言 在unity的游戏开发中,对于异步操作,有一个避免不了的操作: 协程,以前一直理解的懵懵懂懂,最近认真充电了一下 ...
- Unity 协程Coroutine综合测试
using UnityEngine; using System.Collections; using System.Text; public class rotCube : MonoBehaviour ...
- Unity 协程(Coroutine)原理与用法详解
前言: 协程在Unity中是一个很重要的概念,我们知道,在使用Unity进行游戏开发时,一般(注意是一般)不考虑多线程,那么如何处理一些在主任务之外的需求呢,Unity给我们提供了协程这种方式 为啥在 ...
- Unity协程(Coroutine)原理深入剖析
Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 其实协程并没有那么复杂,网上很多地方都说是多 ...
- Unity协程(Coroutine)原理深入剖析(转载)
记得去年6月份刚开始实习的时候,当时要我写网络层的结构,用到了协程,当时有点懵,完全不知道Unity协程的执行机制是怎么样的,只是知道函数的返回值是IEnumerator类型,函数中使用yield r ...
- Unity协程(Coroutine)原理深入剖析再续
Unity协程(Coroutine)原理深入剖析再续 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面已经介绍过对协程(Coroutine ...
- 【转】Unity协程(Coroutine)原理深入剖析
Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 记得去年6月份刚开始实习的时候,当时要我写网 ...
- Unity怎样在Editor下运行协程(coroutine)
在处理Unity5新的AssetBundle的时候,我有一个需求,须要在Editor下(比方一个menuitem的处理函数中,游戏没有执行.也没有MonoBehaviour)载入AssetBundle ...
随机推荐
- Sprint第二个冲刺(第十二天)
一.Sprint 计划会议: 现在商家上传商品的图片的功能已经完成了,正在准备是实现更新商品图片.更新商品价格和商品描述得功能,目前工作进展顺利,进度也慢慢赶上,争取顺利完成目标. 下面是真机测试下的 ...
- Appium 解决不能输入中文字符问题
只需在初始化driver方法时,写这两行代码即可: capabilities.setCapability("unicodeKeyboard", "True" ...
- Git的配置及常用命令
Git配置 git config --global user.name "<username>" git config --global user.email &quo ...
- 利用css3新增选择器制作背景切换
之前写css3的时间都是捡项目需要的来用,没有系统的学习过,这几天好好的补了一下css3的知识,真的获益匪浅!觉得新增的那些选择器是有用至极的!今天就来所这几天的所学做一个点击标签切换背景的效果,是纯 ...
- go_databasetest
go_databasetest go语言的数据库测试: go get github.com/Go-SQL-Driver/MySQL package main import ( _"githu ...
- windowDialog销毁页面的问题
[结贴] windowDialog销毁页面的问题 [复制链接] Ghost丶 15 主题 91 帖子 200 积分 中级会员 积分 200 发消息 1# 电梯直达 发表于 2015-8- ...
- javascript性能优化总结一(转载人家)
一直在学习javascript,也有看过<犀利开发Jquery内核详解与实践>,对这本书的评价只有两个字犀利,可能是对javascript理解的还不够透彻异或是自己太笨,更多的是自己不擅于 ...
- Perl Sort函数用法总结和使用实例
一) sort函数用法 sort LISTsort BLOCK LISTsort SUBNAME LIST sort的用法有如上3种形式.它对LIST进行排序,并返回排序后的列表.假如忽略了SUBNA ...
- sql rollup解决责任人收支余额
问题的提出是周聪之前问过我的项目往来查询,不好在NC上一次性查询到.然后我就搞了一个很长的项目对账,发布了NC的节点. 现在我做了总二的总账,每次领导问我项目还有多少钱,收了多少付了多少,我还要通过科 ...
- mysql 语法总结
设置SQL语句所用的字符编码:set names UTF8; 判断指定的数据库是否存在:DROP DATABASE IF EXISTS 库; 开始使用指定的数据库:USE 库; 创建数据库CREAT ...