本文翻译自Unity官方文档:https://docs.unity3d.com/Manual/Coroutines.html
专有名词:
Coroutine   协程
Alpha   不透明度
当你调用一个函数时,它会在返回之前一直运行到结束。这实际上意味着在一个函数中发生的任何行为都必须在一个帧更新中发生;函数调用不能用于包含过程动画或事件序列。例如,考虑逐步减少对象的alpha(不透明度)值的任务,直到它也变得完全不可见。
void Fade() {
for (float f = 1f; f >= ; f -= 0.1f) {
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
}
}
正如你所看到的实际情况那样,Fade()函数不会有你所期望的效果。为了让渐变变得可见,必须通过一系列帧更新来减少alpha值,以显示正在渲染的中间值。但是,该函数将在单个更新中全部执行了,中间值将永远不会被看到,对象将立即消失。
可以通过向Update()函数添加代码来处理类似的情况,该函数基于逐帧执行渐变。然而,使用Coroutine来完成这类任务通常更加方便。
Coroutine就像这样一个函数,它具有暂停执行和将控制权返回Unity的功能,但在接下来的帧中继续执行。在C#中,Coroutine是这样声明的:
IEnumerator Fade() {
for (float f = 1f; f >= ; f -= 0.1f) {
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield return null;
}
}
它本质是一个函数,它使用返回类型为IEnumerator声明,并且包含在主体的某个地方的yield return语句。yield return那一行是执行暂停的点,并将返回到接下来的帧中。你需要通过StarCoroutine设置协程的运行。
void Update() {
if (Input.GetKeyDown("f")) {
StartCoroutine("Fade");
}
}
在UnityScript中,事情稍微简单一些。任何包含yield语句的函数都被理解为协程(Coroutine),而IEumerator返回类型不需要显式声明。
function Fade() {
for (var f = 1.0; f >= 0; f -= 0.1) {
var c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield;
}
}
同样,可以在UnityScript中启动协程(Coroutine),只需当成一个普通的正常函数调用就可以了。
function Update() {
if (Input.GetKeyDown("f")) {
Fade();
}
}
你会注意到,在Fade()函数中,循环计数器在协程(Coroutine)的声明周期中保持其正确的值。事实上,任何变量或参数都将在yield之间得到正确的保留。
默认情况下,在yield之后,在这一帧中会恢复一个协程(Coroutine),但是也可以使用WaitForSeconds来引入时间延迟。在UnityScript中是这样的:
function Fade() {
for (var f = 1.0; f >= 0; f -= 0.1) {
var c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield WaitForSeconds(0.1);
}
}
这可以作为一种实现一段时间内的类似传播效果的方式,但同时也是一种有用的优化。游戏中的许多任务需要定期进行,最明显的方法是将它们包含在Update函数中。但是,这个函数通常每秒会被调用多次。当一项任务不需要频繁地重复时,你可以把它放入一个协程(Coroutine),以定期更新,但不是每一帧都更新。一个例子可能是警告玩家是否敌人在附近。一般的UnityScript代码看起来像这样子:
function ProximityCheck() {
for (int i = 0; i < enemies.Length; i++) {
if (Vector3.Distance(transform.position, enemies[i].transform.position) < dangerDistance) {
return true;
}
} return false;
}
如果有很多敌人,然后调用这个函数,每一帧都会引入一个显著的开销。但是,你可以用协程(Coroutine)每隔十分之一秒来调用它:
IEnumerator DoCheck() {
for(;;) {
ProximityCheck;
yield return new WaitForSeconds(.1f);
}
}
这将大大减少检查的次数,而不会对游戏性产生任何明显的影响。
注意:当一个MonoBehaviour被禁用(disable)时,协程(Coroutine)并没有停止,但是只有当它被完全摧毁(destroyed)时才会停止。你可以使用MonoBehaviour.StopCoroutine和MonoBehaviour.StopAllCoroutines来停止协程(Coroutine)的执行。当Monobehaviour被摧毁时(destroyed),协程也会停止。
 

Unity脚本编程之——协程(Coroutine)的更多相关文章

  1. Unity协程(Coroutine)管理类——TaskManager工具分享

    博客分类: Unity3D插件学习,工具分享 源码分析   Unity协程(Coroutine)管理类——TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处 ...

  2. [Unity菜鸟] 协程Coroutine

    1.协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态. unity中StartCoroutine()就是协程,协程实际上是在一个线程中, ...

  3. Python并发编程协程(Coroutine)之Gevent

    Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译 ...

  4. Unity协程Coroutine使用总结和一些坑

    原文摘自 Unity协程Coroutine使用总结和一些坑 MonoBehavior关于协程提供了下面几个接口: 可以使用函数或者函数名字符串来启动一个协程,同时可以用函数,函数名字符串,和Corou ...

  5. 并发编程协程(Coroutine)之Gevent

    并发编程协程之Gevent Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate r ...

  6. 【Unity】协程Coroutine及Yield常见用法

    最近学习协程Coroutine,参考了别人的文章和视频教程,感觉协程用法还是相当灵活巧妙的,在此简单总结,方便自己以后回顾.Yield关键字的语意可以理解为“暂停”. 首先是yield return的 ...

  7. (zt)Lua的多任务机制——协程(coroutine)

    原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...

  8. 协程coroutine

    协程(coroutine)顾名思义就是“协作的例程”(co-operative routines).跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程 ...

  9. Lua的多任务机制——协程(coroutine)

    并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定 ...

随机推荐

  1. [shiro学习笔记]第二节 shiro与web融合实现一个简单的授权认证

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/39933993 shiro官网:http://shiro.apache.org/ shi ...

  2. springMVC系列之(四) spring+springMVC+hibernate 三大框架整合

    首先我们要知道Hibernate五大对象:,本实例通过深入的使用这五大对象和spring+springMVC相互结合,体会到框架的好处,提高我们的开发效率 Hibernate有五大核心接口,分别是:S ...

  3. Druid VS Antlr4

    DRUID VS ANTLR4 测试方法 环境:x86_64,eclipse kepler,jdk 6 测试对象:antlr v4,druid手写sql parser模块 测试过程:分别采用单线程.多 ...

  4. Fragment的事务操作&Actvity的状态丢失

    Fragment Transactions & Activity State Loss 本文翻译自Fragment Transactions & Activity State Loss ...

  5. Android摄像头照相机技术-android学习之旅(八)

    简介 Android SDK支持Android设备内置的照相机.从Android2.3开始支持多个摄像头(主要指前置摄像头和后置摄像头).通过照片相可以拍照和录像. 需要考虑的问题 是否支持照相机 快 ...

  6. mqtt推送介绍

    方案1.使用GCM服务(Google Cloud Messaging) 简介:Google推出的云消息服务,即第二代的C2DM. 优点:Google提供的服务.原生.简单,无需实现和部署服务端. 缺点 ...

  7. Linux技巧:一次删除一百万个文件的最快方法

    最初的测评 昨天,我看到一个非常有趣的删除一个目录下的海量文件的方法.这个方法来自http://www.quora.com/How-can-someone-rapidly-delete-400-000 ...

  8. HDU2612---(两次BFS)

    Description Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Nin ...

  9. 【Android 应用开发】 FastJson 使用详解

    博客地址 :http://blog.csdn.net/shulianghan/article/details/41011605 fastjson 源码地址 : -- GitHub : https:// ...

  10. Linux多线程实践(4) --线程特定数据

    线程特定数据 int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *)); int pthread_key_ ...