Cisco设定两个PC端在同一vmware 网络设定下

【转】【UNITY3D 游戏开发之六】UNITY 协程COROUTINE与INVOKE - 推酷
【转】【UNITY3D 游戏开发之六】UNITY 协程COROUTINE与INVOKE
本站文章均为
原创,转载务必在明显处注明:(作者新浪微博:
&原文链接:&
本博客最新动态!及时将最新博文通知您!
这里Himi强调一点:Unity里面的协程并不是线程,协程是在unity主线程中运行的,每一帧中处理一次,而并不与主线程并行。这就意味着在协程之间并不存在着所谓线程间的同步和互斥问题,不会出现死锁。一般来说,访问同一个值也都是很安全的,用协程可以处理绝大多数的小问题,而且不用考虑复杂的线程间同步,还是很方便的。
要说协程的不足就是不能运用处理器的多核来提高处理性能,毕竟这个在运行时事实上是在一个线程中执行的。
【以下均为转载内容】
1. & &&Unity3D ?MonoBehaviour类Invoke,Coroutine :&
2. & &Unity3D协程介绍 以及 使用 :&
3. &U3D 游戏开发中的&yield协程与消息传递 :&
在Unity中,延时执行一段代码或者一个方法或者几个方法的情况非常普遍。
一般会用到Invoke和InvokeRepeating方法。顾名思义,第一个是执行一次,第二个是重复执行。
看下定义:
void Invoke(string methodName, float time);
第一个参数是方法名(注意是字符串形式),并不是更方便的委托。第二个是延时多少秒。只执行一次。
void InvokeRepeating(string methodName, float time, float repeatRate);
InvokeRepeating第二个参数是延时多少秒后开始,第三个参数是每次执行间隔的秒数。
你有没有发现这两个方法有个弊端,就是必须输入方法名!也就是我说,如果我想延时执行某段代码,必须把代码放在某个方法里,然后使用这Invoke或者InvokeRepeating方法来执行。
这样对于上下文变量、属性的引用就会尤为不便,而且不能传参数!!!尼玛,要他还有何用?
我猜你一定用过这样的方法。没错,“协同”,听起来还挺高大上的名字啊。
用StartCoroutine来执行一个以IEnumerator为返回值的方法,通常用于异步下载啊,等比较耗时又不能让游戏卡死的情况。
还有一个好的类WaitForSeconds,对,它就一个构造函数,用来延时的(延时………………比万艾可好用?比希爱力好用?)。
好了不废话了,以下是我自用的延时方法,放在一个类里以静态方法存在。可以在任何时候任何地方延时指定秒数的代码。
using UnityE
using System.C
public class DelayToInvoke : MonoBehaviour
public static IEnumerator DelayToInvokeDo(Action action, float delaySeconds)
yield return new WaitForSeconds(delaySeconds);
如何使用呢?
比如我点击NGUI的一个Button,则
void OnClick()
StartCoroutine(DelayToInvoke.DelayToInvokeDo(() =&
Application.LoadLevel(“Option”);
}, 0.1f));
C#中Invoke 和 BeginInvoke 的区别 :
Coroutine:
尊重他人的劳动,支持原创,转载请注明出处:http.
记得去年6月份刚开始实习的时候,当时要我写网络层的结构,用到了协程,当时有点懵,完全不知道Unity协程的执行机制是怎么样的,只是知道函数的返回值是IEnumerator类型,函数中使用yield return ,就可以通过StartCoroutine调用了。后来也是一直稀里糊涂地用,上网google些基本都是例子,很少能帮助深入理解Unity协程的原理的。
本文只是从Unity的角度去分析理解协程的内部运行原理,而不是从C#底层的语法实现来介绍(后续有需要再进行介绍),一共分为三部分:
线程(Thread)和协程(Coroutine)
Unity中协程的执行原理
IEnumerator & Coroutine
之前写过一篇《
》主要是介绍TaskManager实现对协程的状态控制,没有Unity后台实现的协程的原理进行深究。虽然之前自己对协程还算有点了解了,但是对Unity如何执行协程的还是一片空白,在上看到两篇讲解Coroutine,如数家珍,当我看到Advanced Coroutine后面的Hijack类时,顿时觉得十分精巧,眼前一亮,遂动了写文分享之。
线程(Thread)和协程(Coroutine)
D.S.Qiu觉得使用协程的作用一共有两点:1)延时(等待)一段时间执行代码;2)等某个操作完成之后再执行后面的代码。总结起来就是一句话:控制代码在特定的时机执行。
很多初学者,都会下意识地觉得协程是异步执行的,都会觉得协程是C# 线程的替代品,是Unity不使用线程的解决方案。
所以首先,请你牢记:协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。
Unity中协程的执行原理
<给出了协程的定义:
A coroutine is a function that is executed partially and, presuming suitable conditions are met, will be resumed at some point in the future until its work is done.
即协程是一个分部执行,遇到条件(yield return 语句)会挂起,直到条件满足才会被唤醒继续执行后面的代码。
Unity在每一帧(Frame)都会去处理对象上的协程。Unity主要是在Update后去处理协程(检查协程的条件是否满足),但也有写特例:
从上图的剖析就明白,协程跟Update()其实一样的,都是Unity每帧对会去处理的函数(如果有的话)。如果MonoBehaviour 是处于激活(active)状态的而且yield的条件满足,就会协程方法的后面代码。还可以发现:如果在一个对象的前期调用协程,协程会立即运行到第一个 yield return 语句处,如果是 yield return null ,就会在同一帧再次被唤醒。如果没有考虑这个细节就会出现一些奇怪的问题『1』。
『1』注 图和结论都是从 上得来的,经过下面的验证发现与实际不符,D.S.Qiu用的是Unity 4.3.4f1 进行测试的。 经过测试验证,协程至少是每帧的LateUpdate()后去运行。
下面使用 yield return new WaitForSeconds(1f); 在Start,Update 和 LateUpdate 中分别进行测试:
using UnityE
using System.C
public class TestCoroutine&:&MonoBehaviour&{
private bool isStartCall&=& false ;&& //Makesure&Update()&and&LateUpdate()&Log&only&once
private bool isUpdateCall&=& false ;
private bool isLateUpdateCall&=& false ;
//&Use&this&for&initialization
void Start&()&{
if (!isStartCall)
Debug.Log( “Start&Call&Begin” );
StartCoroutine(StartCoutine());
Debug.Log( “Start&Call&End” );
isStartCall&=& true ;
IEnumerator&StartCoutine()
Debug.Log( “This&is&Start&Coroutine&Call&Before” );
yield& return new WaitForSeconds(1f);
Debug.Log( “This&is&Start&Coroutine&Call&After” );
//&Update&is&called&once&per&frame
void Update&()&{
if (!isUpdateCall)
Debug.Log( “Update&Call&Begin” );
StartCoroutine(UpdateCoutine());
Debug.Log( “Update&Call&End” );
isUpdateCall&=& true ;
IEnumerator&UpdateCoutine()
Debug.Log( “This&is&Update&Coroutine&Call&Before” );
yield& return new WaitForSeconds(1f);
Debug.Log( “This&is&Update&Coroutine&Call&After” );
void LateUpdate()
if (!isLateUpdateCall)
Debug.Log( “LateUpdate&Call&Begin” );
StartCoroutine(LateCoutine());
Debug.Log( “LateUpdate&Call&End” );
isLateUpdateCall&=& true ;
IEnumerator&LateCoutine()
Debug.Log( “This&is&Late&Coroutine&Call&Before” );
yield& return new WaitForSeconds(1f);
Debug.Log( “This&is&Late&Coroutine&Call&After” );
得到日志输入结果如下:
然后将yield return new WaitForSeconds(1f);改为 发现日志输入结果和上面是一样的,没有出现上面说的情况:
using UnityE
using System.C
public class TestCoroutine&:&MonoBehaviour&{
private bool isStartCall&=& false ;&& //Makesure&Update()&and&LateUpdate()&Log&only&once
private bool isUpdateCall&=& false ;
private bool isLateUpdateCall&=& false ;
//&Use&this&for&initialization
void Start&()&{
if (!isStartCall)
Debug.Log( “Start&Call&Begin” );
StartCoroutine(StartCoutine());
Debug.Log( “Start&Call&End” );
isStartCall&=& true ;
IEnumerator&StartCoutine()
Debug.Log( “This&is&Start&Coroutine&Call&Before” );
yield& return null ;
Debug.Log( “This&is&Start&Coroutine&Call&After” );
//&Update&is&called&once&per&frame
void Update&()&{
if (!isUpdateCall)
Debug.Log( “Update&Call&Begin” );
StartCoroutine(UpdateCoutine());
Debug.Log( “Update&Call&End” );
isUpdateCall&=& true ;
IEnumerator&UpdateCoutine()
Debug.Log( “This&is&Update&Coroutine&Call&Before” );
yield& return null ;
Debug.Log( “This&is&Update&Coroutine&Call&After” );
void LateUpdate()
if (!isLateUpdateCall)
Debug.Log( “LateUpdate&Call&Begin” );
StartCoroutine(LateCoutine());
Debug.Log( “LateUpdate&Call&End” );
isLateUpdateCall&=& true ;
IEnumerator&LateCoutine()
Debug.Log( “This&is&Late&Coroutine&Call&Before” );
yield& return null ;
Debug.Log( “This&is&Late&Coroutine&Call&After” );
『今天意外发现Monobehaviour的函数执行顺序图,发现协程的运行确实是在LateUpdate之后,下面附上:』
增补于:03/12/
前面在介绍
时,说到MonoBehaviour 没有针对特定的协程提供Stop方法,其实不然,可以通过MonoBehaviour enabled = false 或者 gameObject.active = false 就可以停止协程的执行『2』。
经过验证,『2』的结论也是错误的,正确的结论是,MonoBehaviour.enabled = false 协程会照常运行,但 gameObject.SetActive(false) 后协程却全部停止,即使在Inspector把 &gameObject 激活还是没有继续执行:
using UnityE
using System.C
public class TestCoroutine&:&MonoBehaviour&{
private bool isStartCall&=& false ;&& //Makesure&Update()&and&LateUpdate()&Log&only&once
private bool isUpdateCall&=& false ;
private bool isLateUpdateCall&=& false ;
//&Use&this&for&initialization
void Start&()&{
if (!isStartCall)
Debug.Log( “Start&Call&Begin” );
StartCoroutine(StartCoutine());
Debug.Log( “Start&Call&End” );
isStartCall&=& true ;
IEnumerator&StartCoutine()
Debug.Log( “This&is&Start&Coroutine&Call&Before” );
yield& return new WaitForSeconds(1f);
Debug.Log( “This&is&Start&Coroutine&Call&After” );
//&Update&is&called&once&per&frame
void Update&()&{
if (!isUpdateCall)
Debug.Log( “Update&Call&Begin” );
StartCoroutine(UpdateCoutine());
Debug.Log( “Update&Call&End” );
isUpdateCall&=& true ;
this .enabled&=& false ;
//this.gameObject.SetActive(false);
IEnumerator&UpdateCoutine()
Debug.Log( “This&is&Update&Coroutine&Call&Before” );
yield& return new WaitForSeconds(1f);
Debug.Log( “This&is&Update&Coroutine&Call&After” );
yield& return new WaitForSeconds(1f);
Debug.Log( “This&is&Update&Coroutine&Call&Second” );
void LateUpdate()
if (!isLateUpdateCall)
Debug.Log( “LateUpdate&Call&Begin” );
StartCoroutine(LateCoutine());
Debug.Log( “LateUpdate&Call&End” );
isLateUpdateCall&=& true ;
IEnumerator&LateCoutine()
Debug.Log( “This&is&Late&Coroutine&Call&Before” );
yield& return null ;
Debug.Log( “This&is&Late&Coroutine&Call&After” );
先在Update中调用 this.enabled = 得到的结果:
然后把 this.enabled = 注释掉,换成 this.gameObject.SetActive(false); 得到的结果如下:
:通过设置MonoBehaviour脚本的enabled对协程是没有影响的,但如果 gameObject.SetActive(false) 则已经启动的协程则完全停止了,即使在Inspector把gameObject 激活还是没有继续执行。也就说协程虽然是在MonoBehvaviour启动的(StartCoroutine)但是协程函数的地位完全是跟MonoBehaviour是一个层次的,不受MonoBehaviour的状态影响,但跟MonoBehaviour脚本一样受gameObject 控制,也应该是和MonoBehaviour脚本一样每帧“轮询” yield 的条件是否满足。
yield 后面可以有的表达式:
a) null ? the coroutine executes the next time that it is eligible
b) WaitForEndOfFrame ? the coroutine executes on the frame, after all of the rendering and GUI is complete
c) WaitForFixedUpdate ? causes this coroutine to execute at the next physics step, after all physics is calculated
d) WaitForSeconds ? causes the coroutine not to execute for a given game time period
e) WWW ? waits for a web request to complete (resumes as if WaitForSeconds or null)
f) Another coroutine ? in which case the new coroutine will run to completion before the yielder is resumed
值得注意的是 WaitForSeconds()受Time.timeScale影响,当Time.timeScale = 0f 时,yield return new WaitForSecond(x) 将不会满足。
IEnumerator & Coroutine
协程其实就是一个IEnumerator(迭代器),IEnumerator 接口有两个方法 Current 和 MoveNext() ,前面介绍的
就是利用者两个方法对协程进行了管理,只有当MoveNext()返回 true时才可以访问 Current,否则会报错。迭代器方法运行到 yield return 语句时,会返回一个expression表达式并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。
Unity在每帧做的工作就是:调用 协程(迭代器)MoveNext() 方法,如果返回 true ,就从当前位置继续往下执行。
这里在介绍一个协程的交叉调用类 Hijack(参见附件):
using System.Collections.G
using System.L
using UnityE
using System.C
[RequireComponent( typeof (GUIText))]
public class Hijack&:&MonoBehaviour&{
//This&will&hold&the&counting&up&coroutine
IEnumerator&_countUp;
//This&will&hold&the&counting&down&coroutine
IEnumerator&_countD
//This&is&the&coroutine&we&are&currently
//hijacking
IEnumerator&_
//A&value&that&will&be&updated&by&the&coroutine
//that&is&currently&running
int value&=&0;
void Start()
//Create&our&count&up&coroutine
_countUp&=&CountUp();
//Create&our&count&down&coroutine
_countDown&=&CountDown();
//Start&our&own&coroutine&for&the&hijack
StartCoroutine(DoHijack());
void Update()
//Show&the&current&value&on&the&screen
guiText.text&=&value.ToString();
void OnGUI()
//Switch&between&the&different&functions
if (GUILayout.Button( “Switch&functions” ))
if (_current&==&_countUp)
_current&=&_countD
_current&=&_countUp;
IEnumerator&DoHijack()
while ( true )
//Check&if&we&have&a&current&coroutine&and&MoveNext&on&it&if&we&do
if (_current&!=& null &&&_current.MoveNext())
//Return&whatever&the&coroutine&yielded,&so&we&will&yield&the
//same&thing
yield& return _current.C
//Otherwise&wait&for&the&next&frame
yield& return null ;
IEnumerator&CountUp()
//We&have&a&local&increment&so&the&routines
//get&independently&faster&depending&on&how
//long&they&have&been&active
float increment&=&0;
while ( true )
//Exit&if&the&Q&button&is&pressed
if (Input.GetKey(KeyCode.Q))
increment+=Time.deltaT
value&+=&Mathf.RoundToInt(increment);
yield& return null ;
IEnumerator&CountDown()
float increment&=&0f;
while ( true )
if (Input.GetKey(KeyCode.Q))
increment+=Time.deltaT
value&-=&Mathf.RoundToInt(increment);
//This&coroutine&returns&a&yield&instruction
yield& return new WaitForSeconds(0.1f);
上面的代码实现是两个协程交替调用,对有这种需求来说实在太精妙了。
今天仔细看了下 有关Coroutine的两篇文章,虽然第一篇(参考①)现在验证的结果有很多错误,但对于理解协程还是不错的,尤其是当我发现Hijack这个脚本时,就迫不及待分享给大家。
本来没觉得会有上的文章会有错误的,无意测试了发现还是有很大的出入,当然这也不是说原来作者没有经过验证就妄加揣测,D.S.Qiu觉得很有可能是Unity内部的实现机制改变了,这种东西完全可以改动,Unity虽然开发了很多年了,但是其实在实际开发中还是有很多坑,越发觉得Unity的无力,虽说容易上手,但是填坑的功夫也是必不可少的。
看来很多结论还是要通过自己的验证才行,贸然复制粘贴很难出真知,切记!
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Unity3D(31)
(一)协程
开启方法:StartCoroutine(&函数名&);
结束方法StopCoroutine(&函数名&),StopAllCoroutines();
IEnumerator TestIEnumerator()
Debug.Log(&协程&);
//等待游戏界面绘制完成
yield return new WaitForEndOfFrame();
Debug.Log(&游戏界面绘制完成&);
//等待1秒后
yield return new WaitForSeconds(1F);
Debug.Log(&1秒后&);
//等待0.5秒后
yield return new WaitForSeconds(0.5F);
Debug.Log(&0.5秒后&);
while(true)
//等待固定更新
yield return new WaitForFixedUpdate();
Debug.Log(&固定更新&);
// Use this for initialization
void Start () {
StartCoroutine(&TestIEnumerator&);
(二)调用函数
不重复调用
Invoke(&函数名&,“延迟时间”); 重复调用 InvokeRepeating(&函数名&,“延迟时间”,“重复间隔时间”);
CancelInvoke(&函数名&),CancelInvoke();
是否在有在调用的函数
IsInvoking(); 指定函数是否在调用 IsInvoking(&函数名&);
void TestInvokeRepeating()
Debug.Log(&重复调用&);
m_round++;
if (m_round & 15)
//结束所有调用
//CancelInvoke();
//结束指定调用
CancelInvoke(&TestInvokeRepeating&);
if (IsInvoking(&TestInvokeRepeating&))
Debug.Log(&调用中&);
Debug.Log(&不在调用中&);
void TestInvokeRepeating2()
Debug.Log(&重复调用TestInvokeRepeating2&);
// Use this for initialization
void Start () {
m_round = 0;
InvokeRepeating(&TestInvokeRepeating&,0f,1f);
InvokeRepeating(&TestInvokeRepeating2&, 0f, 1f);
(二)委托
public class GameManager : MonoBehaviour
//定义一个委托
delegate int TestEntrust(int a);
public int ReceiveLogic(int a)
Debug.Log(&参数a=&+a);
// Use this for initialization
void Start () {
//创建委托对象
TestEntrust rl = new TestEntrust(ReceiveLogic);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:243893次
积分:3049
积分:3049
排名:第9579名
原创:48篇
转载:44篇
评论:51条
阅读:57092
阅读:10435
文章:28篇
阅读:74589
(2)(6)(2)(4)(9)(4)(4)(7)(15)(8)(2)(3)(2)(1)(2)(1)(2)(2)(1)(1)(5)(1)(8)阅读(7379)
  1. 协程
  在Unity 3D中,我们刚开始写脚本的时候肯定会遇到类似下面这样的需求:每隔3秒发射一个烟花、怪物死亡后20秒再复活之类的。刚开始的时候喜欢把这些东西都塞到Update里面去,就像下面这样写。
1 float nowTime = 3.0f;
2 bool isDead = true;
3 float deadTime = 20.0f;
5 void startFireworks()
10 void revival()
15 void Update ()
if (nowTime &= 0)
startFireworks();
nowTime = Random.Range(2.5f, 3.5f);
nowTime -= Time.deltaT
if (isDead)
if (deadTime &= 0)
revival();
isDead = false;
deadTime = 30.0f;
deadTime -= Time.deltaT
  当这样的需求多起来时,Update中凌乱不堪,如果有需求需要添加或者修改,将显得非常麻烦。尤其是类似死亡后复活这种需求,只是在死亡后等待30秒重新复活,其他时间根本不需要去执行,这样放在Update里面还需要每一帧去判断,显得很累赘。
好在Unity 3D支持yield协程,不懂没关系,先看看下面用协程实现上面的功能。
1 void Start()
StartCoroutine(Fireworks());
6 void deadHandle()
StartCoroutine(Revival());
11 IEnumerator Fireworks()
while (true)
startFireworks();
yield return new WaitForSeconds(Random.Range(2.5f, 3.5f));
20 IEnumerator Revival()
yield return new WaitForSeconds(30.0f);
revival();
  上面代码中,以IEnumerator作为返回值的函数就是协程,调用StartCoroutine()开始协程,在Start函数中调用StartCoroutine(Fireworks());,说明在开始时就开始执行协程Fireworks(),在deadHandle()中调用StartCoroutine(Revival());说明是在怪物死亡时开始执行协程。
  现在再来看看协程Fireworks()和Revival()中带有yield return的语句,yield return new WaitForSeconds(30.0f);表示现在从return这个语句处中断执行,在30秒后继续执行后面的代码。
  如果想在下一帧继续执行,就应该这样写 yield return null,这样语句就会在return这里中断,等待下一帧继续执行后面的代码。就像在Fireworks()里面写的,return之后,继续进行while判断,为true则继续循环,遇到yield return中断执行,等待,反复这样运行,就像Update一样。当然while中的判断条件可以自己指定,在需要中断的时候,在外面将while中的判断条件置为false即可。
1 bool isContinue = true;
2 void stopFireworks()
isContinue = false;
6 IEnumerator Fireworks()
while (isContinue)
startFireworks();
yield return new WaitForSeconds(Random.Range(2.5f, 3.5f));
  当然也可以通过有StopCoroutine来中止协程的执行,不过这个函数是有条件的,具体可以去查阅unity文档或者网上搜索一下,有很多资料,这里只是告诉大家有这么个东西可以用。
  有了协程,写起脚本来真是方便了很多。协程和Update一样,也是系统在每帧会去检测调用,因此在协程中也是可以使用Time.deltaTime的。关于协程与Update之类的执行顺序,没有测试过,网上也有一些资料,大家可以参考,不同的Unity 3D版本具体的实现可能有出入,如果某些功能确实需要知道执行顺序,那么到时候可以亲测一下。
  需要注意的一点是:WaitForSeconds是受到Time.timeScale影响的,如果将其置为0,那么协程就无法执行下去了。不过yield return null不会受到影响,因为每帧会执行,只是Time.deltaTime为0了。
  2. 消息传递
  在游戏开发中,消息传递必不可少。通常有三种方式:保存别的对象的引用、Unity自带的SendMessage和C#中的事件。
  例如一个暂停,我需要通知玩家,暂停了,不要响应键盘鼠标操作了;通知UI,显示一个暂停面板;通过所有怪物,不要动了,暂停了,休息一下。&
  第一种方式是刚开始写脚本时常用的,保存所有对象的引用,这是很麻烦的事情,我需要获取玩家、UI和所有的怪物对象,然后调用其相应的暂停函数,这在程序规模变大之后,添加、修改和删除是一个很大的工作量。而且很多对象之间相互引用,耦合对也很高,用起来比较麻烦。
  第二种方式是Unity 3D提供的Messages消息机制,不过网上说这种方法有很大的缺陷,而且只能通知一个父子关系的对象,不同对象之间的消息无法传递。没有用过这个机制,所以也不是很清楚是不是像上面说的那样。
  第三种方式是C#中的委托和事件,这个方法对于消息传递来说非常好用,从设计模式的角度上来说,就是一个典型的观察者模式。如果你用过EasyTouch摇杆,那你就应该知道在OnEnable()中使用EasyJoystick.On_JoystickMove += OnJoystickM注册自己的Move函数,在这里就是OnJoystickMove。其实EasyTouch这个就用到了C#事件,使用+=添加自己的响应函数,当发生摇杆移动时,就会调用你自己指定的OnJoystickMove函数。具体可以参考下面给出的参考资料的链接。
  今天就写到这里,这些都是简介性质的,详细资料网上都有很多,我这些只是告诉初学者Unity 3D中有这些东西,很可能是你需要的,可以少走一些弯路。
  关于协程和C#事件,是Unity 3D中强力推荐的两个机制,它们真的非常重要,一定要善用,大家可以体会一下。
  参考资料1:
  参考资料2:
&原文链接:
阅读排行榜Unity 协程管理器和协程回调函数
Unity 协程管理器和协程回调函数
The Unity3D
& & &unity中使用协程的时候,会经常遇到两个问题。
绑定在GameObject上的协程,会因为Active false而终止运行。当使用一个协程的时候,如果注册一个通过的回调函数,来处理结果,并且可以拿到协程返回的&#20540;。
& & & 第一个问题,可以使用一个协程管理器。挂在独立的GameObject上,不会受到操作的GameObject的active状态影响。
& & & 第二个问题,在协程函数里,自然我们拿到协程完成的结果,并调用回调。但是不够通用,需要在每个协程函数里写同样的调用。我们可以通过给协程注入一个回调函数来统一处理,并传入协程的返回&#20540;。
& & & &using UnityE
using System.C
using System.Collections.G
public static class ACoroutineManager
private class
InnerCoroutine : MonoBehaviour {}
private static InnerC
static ACoroutineManager()
if (coroutine == null)
coroutine = new GameObject(&ACoroutineManager&).AddComponent&InnerCoroutine&();
GameObject.DontDestroyOnLoad(coroutine);
public static Coroutine StartCoroutineTask(IEnumerator routine)
return coroutine.StartCoroutine(routine);
private static IEnumerator StartInnerCoroutine(IEnumerator routine, Action&object& callback)
yield return StartCoroutineTask(routine);
callback(routine.Current);
public static void StartCoroutineTask(IEnumerator routine, Action&object& callback)
StartCoroutineTask(StartInnerCoroutine(routine, callback));
public static void StopCoroutineTask(IEnumerator routine)
coroutine.StopCoroutine(routine);
public static void StopAllCoroutineTask()
coroutine.StopAllCoroutines();
& & & &协程管理器,会生成一个独立GameObject挂在一个MonoBehaviour,所有的协程执行都是由这个脚本发起。回调函数,就在于routine的Current属性。我们知道,协程其实是一个迭代器在执行。迭代器的当前&#20540;就是Current,这个&#20540;就是协程函数里yield return object 返回的这个object。
我的热门文章
即使是一小步也想与你分享

我要回帖

更多关于 ubantu 设定ssh端口 的文章

 

随机推荐