我是快乐的搬运工 http://blog.csdn.net/u011397120/article/details/61236055

---------------------------------------------------------------------- 分割线 xx --------------------------------------------------------------------------

本文是个人对Unity协程的一些理解和总结.Unity协程长的有点像线程,但却不是线程.因为协程仍然是在主线程中执行,且在使用时不用考虑同步与锁的问题.协程只是控制代码等到特定的时机后再执行后续步骤.

启动协程

Unity 5.x中使用StartCoroutine方法开启协程,其方式有以下几种.

//形式一
StartCoroutine(CustomCorutineFn());
StartCoroutine(CustomCorutineFn(7));//向方法中传递参数
//形式二
StartCoroutine(“CustomCorutineFn”);
StartCoroutine(“CustomCorutineFn”,7);//向方法中传递参数

以上两种形式都可开起当前MonoBehaviour对象的协程,注意:当你想停止MonoBehaviour对象中的某个协程时,开启与停止协程需要使用相同的形式,不可混合使用.
协程中有多种等待方式,例如:等到FixedUpdate结束后才执行,代码如下.

    bool canExcute = true;
void FixedUpdate()
{
if (canExcute)
{
Debug.Log("FixedUpdate" );
}
}
IEnumerator Corutine_WaitForFixedUpdate()
{
yield return new WaitForFixedUpdate();
Debug.Log(string .Format("====>{0} time:{1}", 1, Time .time));
yield return new WaitForFixedUpdate();
Debug.Log(string .Format("====>{0} time:{1}", 2, Time .time));
}

输出结果如下.

官方文档Monobehaviour的函数执行顺序图,就对协程再次执行的时机做了很好的描述.

以上只是一个示意图,详细信息请看官方文档.
链接 https://docs.unity3d.com/Manual/ExecutionOrder.html

yield null:协程将在下一帧所有脚本的Update执行之后,再继续执行.
yield WaitForSeconds:协程在延迟指定时间,且当前帧所有脚本的 Update全都执行结束后才继续执行.
yield WaitForFixedUpdate:协程在所有脚本的FixedUpdate执行之后,再继续执行.
yield WWW:协程在WWW下载资源完成后,再继续执行.
yield StartCoroutine:协程在指定协程执行结束后,再继续执行.
WaitForSecondsRealtime:与WaitForSeconds类似,但不受时间缩放影响.
WaitWhile:当返回条件为假时才执行后续步骤.

协程的执行也会受到其他因素的影响,例如:当时间缩放值Time.timeScale被修改后,放大或者缩小.FixedUpdate 方法会受影响,则WaitForFixedUpdate也会跟着受影响;当Update方法中同步加载较大的对象时,WaitForSeconds所指定的时间就可能会与实际的时间不一致.所以在执行协程等待时,要视情况而定.

多个gameObject对象开启协程,执行顺序又是如何呢?
假如场景中存在A,B两个gameObject对象,均使用WaitForFixedUpdate方式等待,则等待执行的部分,会在A,B两个对象的FixedUpdate都执行结束后,才开始执行当前帧后续可执行的部分.源码如下:

    void Awake()
{
StartCoroutine(Corutine_WaitForFixedUpdate());
}
IEnumerator Corutine_WaitForFixedUpdate()
{
Debug.Log(string .Format("A : {0}", 0));
yield return new WaitForFixedUpdate();
Debug.Log(string .Format("A : {0}", 1));
}
bool canExcute = false;
void FixedUpdate()
{
if (!canExcute)
{
canExcute = true;
Debug.Log("A FixedUpdate" );
}
}

执行后,输出结果如下.

停止协程

在开发中可能会开启多个协程,如果你想停止其中某个协程,你可使用StopCoroutine.但在使用时,你需要注意一点,停止协程的方式要与开启协程的方式一致.StopCoroutine(“CustomCorutineFn”)必须与StartCoroutine(“CustomCorutineFn”)成对使用,与StartCoroutine(CustomCorutineFn())一起使用则完全无效.
通过StopCoroutine的重载方法可知道,还有两种方式可停止协程.在此举个例子,如下:

    IEnumerator cor;
void Awake()
{
//注意保存IEnumerator变量.
cor = Corutine_WaitForFixedUpdate();
StartCoroutine(cor);
StartCoroutine(Corutine_Stop());
}
IEnumerator Corutine_WaitForFixedUpdate()
{
Debug.Log(string .Format("A : {0}", 0));
yield return new WaitForEndOfFrame();
Debug.Log(string .Format("A : {0}", 1));
}
IEnumerator Corutine_Stop()
{
yield return new WaitForFixedUpdate();
//通过cor停止协程
//而不是this.StopCoroutine(Corutine_WaitForFixedUpdate());
this.StopCoroutine(cor);
}

如果想停止多个协程,可使用StopAllCoroutines方法,但这种方法只能停止当前MonoBehaviour类实例中所有协程.其他不受影响.
如果想停止gameObject上所有脚本组件中的协程,禁用脚本组件是无法停止协程的,只需要禁用gameObject即可.

如何用协程的输出10组计数(每组5次,每次1秒)?
源码如下:

using System.Collections;
using UnityEngine; public class mCorutine : MonoBehaviour
{
public float time = 1;
void Awake()
{
StartCoroutine(FirstLayerCorutine());
}
IEnumerator FirstLayerCorutine()
{
for (int i = 0; i < 10; i++)
{
Debug.Log(string .Format("第{0}组", i + 1));
yield return StartCoroutine(SecondLayerCorutine());
}
}
IEnumerator SecondLayerCorutine()
{
for (int i = 0; i < 5; i++)
{
Debug.Log(string .Format("{0}", i + 1));
yield return new WaitForSeconds(time);
}
}
}

协程的使用还有很多要注意的地方,在这里分享一个关于协程运行时的监控和优化的链接.
http://gulu-dev.com/post/perf_assist/2016-12-20-unity-coroutine-optimizing

Unity3D 协程的介绍和使用的更多相关文章

  1. Unity3D协程yield的理解

    Unity3D的协程概括地将就是:对于一段程序,你可以加上yield标明哪里需要暂停,然后在下一帧或者一段时间后,系统会继续执行这段代码.协程的作用:①延迟一段时间执行代码.②等某个操作完成之后再执行 ...

  2. [转]Unity3D协程介绍 以及 使用

    作者ChevyRay ,2013年9月28日,snaker7译  原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...

  3. Unity3D协程介绍 以及 使用

    作者ChevyRay ,2013年9月28日,snaker7译  原文地址:http://unitypatterns.com/introduction-to-coroutines/ 在Unity中,协 ...

  4. Unity3d 协程的注意问题(新手须注意,老手须加勉)

    关于unity3d的协程,非常的好用,比如等待几秒执行,等待下一帧执行等! 但是也有潜在的问题: 1.协程是单线程的,在主线程中完成 2.如果发现yield, 那么这一帧会结束,那么等下一帧调用此脚本 ...

  5. Unity3D 协程 浅谈

    协程 理解:协程不是线程,也不是异步执行(知道就行). 1.协程和MonoBehaviour的Update函数一样,也是在MainThread中执行的(一定得明白这句话意思). void Start ...

  6. Unity3d 协程

    参考文章: http://blog.csdn.net/onafioo/article/details/48979939 http://www.cnblogs.com/zhaoqingqing/p/37 ...

  7. Unity3D协程

    协程介绍 Unity的协程系统是基于C#的一个简单而强大的接口 ,IEnumerator,它允许你为自己的集合类型编写枚举器.这一点你不必关注太多,我们直接进入一个简单的例子来看看协程到底能干什么.首 ...

  8. Unity3D协程(转)

    这篇文章转自:http://blog.csdn.net/huang9012/article/details/38492937 协程介绍 在Unity中,协程(Coroutines)的形式是我最喜欢的功 ...

  9. Unity3D 协程 Coroutine

    协程(Coroutine)的概念存在于很多编程语言,例如Lua.ruby等.而由于Unity3D是单线程的,因此它同样实现了协程机制来实现一些类似于多线程的功能,但是要明确一点协程不是进程或线程,其执 ...

随机推荐

  1. Uncaught Error: Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3

    前端导入静态页面的时候有一个报错,主要问题是冲突了 Uncaught Error: Bootstrap's JavaScript requires jQuery version 1.9.1 or hi ...

  2. open-source--攻防世界

    题目直接给了源码,发现只要跳过条件就可以得到flag

  3. solus linux 中文输入法

    默认用ibus输入框架,安装ibus-libpinyin sudo eopkg install ibus-libpinyin ibus 安装好后重启 在系统设置 -区域和语言中添加中文,(记得自己设置 ...

  4. Day7 - D - The Euler function HDU - 2824

    The Euler function phi is an important kind of function in number theory, (n) represents the amount ...

  5. eshop5-maven 安装

    1. Maven 安装 2.下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.0.5/binaries/ 3. 通过ta ...

  6. 从0开始自己配置一个vps虚拟服务器(2)

    配置php环境 1.安装php安装所依赖的包 yum -y install gcc gcc-c++ libxml2 libxml2-devel 2.cd usr/local/src 进入目录,在这个目 ...

  7. MongoDB_02简介

    MongoDB简介 MongoDB是一个开源,高性能,无模式的文档型数据库. 它支持的数据结构非常松散,是一种类似于JSON的格式叫BSON,所以他既可以存储比较复杂的数据类型,又相当的灵活. Mon ...

  8. UVA - 10817 Headmaster's Headache (状压dp+记忆化搜索)

    题意:有M个已聘教师,N个候选老师,S个科目,已知每个老师的雇佣费和可教科目,已聘老师必须雇佣,要求每个科目至少两个老师教的情况下,最少的雇佣费用. 分析: 1.为让雇佣费尽可能少,雇佣的老师应教他所 ...

  9. 【docker】docker持续集成CI/持续部署CD

    持续集成(CI) 持续集成(Continuous integration)是一种流行的软件开发实践.集成是指开发将自己本地的代码提交到git等远端仓库上,那么持续集成就是每天多次提交,提早提交代码. ...

  10. Python 中 unittest 框架加载测试用例的常用方法

    unittest 当中为我们提供了许多加载用例的方法,这里说下常用的两种方法...推荐使用第二种 第一种加载测试用例的方法:使用加载器加载两个模块 需要把所有的模块加载到套件中 那么就可以自动的运行所 ...