本文翻译自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. Linux系统编程---守护进程

    守护进程是什么?就是在后台运行的进程. 那么如何创建守护进程呢? 1. 创建孤儿进程 2. setsid() 创建进程会话 3. 重定向标准输入, 标准输出 4. chdir, 改当当前进程的工作目录 ...

  2. Java基础--Java---IO流------GUI(布局)、Frame、事件监听机制、窗体事件、Action事件、鼠标事件、对话框Dialog、键盘事件、菜单

     * 创建图形化界面  * 1.创建frame窗体  * 2.对窗体进行基本设置  *   比如大小.位置.布局  * 3.定义组件  * 4.将组件通过窗体的add方法添加到窗体  * 5.让窗体显 ...

  3. 开源项目——小Q聊天机器人V1.1

    小Q聊天机器人V1.0 http://blog.csdn.net/baiyuliang2013/article/details/51386281 小Q聊天机器人V1.1 http://blog.csd ...

  4. (一〇七)iPad开发之modal的切换方式与展示方式

    在iPad上modal有四种切换方式,分别是竖直进入(由下到上,默认方式).水平翻转.淡入淡出. 属性要设置在将要modal出来的控制器上: /* typedef NS_ENUM(NSInteger, ...

  5. SpringMVC系列之(一) 入门实例

    Spring MVC是非常优秀的MVC框架,由其是在3.0版本发布后,现在有越来越多的团队选择了Spring3 MVC了.Spring MVC结构简单,应了那句话简单就是美,而且他强大不失灵活,性能也 ...

  6. 消息字节——MessageBytes

    在tomcat核心处理中有这么一个需求--"为了提高编码性能,对于socket接收到的字节流不马上进行某种编码的转码,而是应该保留字节流的形式,在需要时.在指定编码时才进行转码工作" ...

  7. 【一天一道LeetCode】#237. Delete Node in a Linked List

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Write a ...

  8. boost::coroutine 无法显示调用栈

    boost::coroutine 无法显示调用栈(金庆的专栏)一例因 boost::format() 格式化参数个数错误造成的 coredump,因为使用了 boost::coroutine, 无法显 ...

  9. UNIX网络编程——TCP输出,UDP输出

    TCP输出 每一个TCP套接字有一个发送缓冲区,我们可以使用SO_SNDBUF套接字选项来更改该缓冲区的大小.当某个应用进程调用write时,内核从该应用进程的缓冲区中复制所有数据到(或是应用程序的缓 ...

  10. 如何在Cocos2D游戏中实现A*寻路算法(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...