文档章节

协同程序(Coroutines)

LIndieGS
 LIndieGS
发布于 2017/06/05 14:35
字数 804
阅读 0
收藏 0

原文链接:https://docs.unity3d.com/Manual/Coroutines.html

    当你调用一个函数,它先与返回运行结束。这意味着,任何一个发生在函数里的动作必须发生在一个单独的帧刷新里;函数的调用不能被用来包含一个程序化的动画或一个持续一段时间的一系列事件。例如,考虑这样的情况,不断减少一个物体的初值(不透明度)知道它变得完全不可见。

void Fade() {
    for (float f = 1f; f >= 0; f -= 0.1f) {
        Color c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
    }
}

    实际上,这个函数不会像你希望那样执行。为了使这个淡出效果可视化,初值必须在连续的几帧内不断减少,去显示不断被渲染的中间值。可是,函数会在一帧刷新内就执行结束,这些中间值就不能显示出来,物体也会立即消失。

    解决方案就是在Update函数里加一些代码,这些代码能使淡出效果逐帧显示。但是,更常用的方法是使用coroutine。

    coroutine就像一个函数,它具有暂停函数执行并把控制权交给Unity的能力,同时,能在下一帧里,让函数从暂停的地方继续执行。在C#中,coroutine是这样声明的:

IEnumerator Fade() {
    for (float f = 1f; f >= 0; f -= 0.1f) {
        Color c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
        yield return null;
    }
}

    它本质上是一个函数,返回值类型是IEnumerator。它还有一个yield return语句,这是实现coroutine功能的关键,也就是暂停程序,在下一帧继续着个功能。为了能使coroutine运行起来,你需要使用StartCoroutine函数:

void Update() {
    if (Input.GetKeyDown("f")) {
        StartCoroutine("Fade");
    }
}

    你需要注意这个Fade函数中的这循环语句,它是保证在coroutine的生命期里,值的正确性。事实上,任何变量或参数都能准确的保存在yield里。

    一帧画面里,coroutine默认在它yield之后继续执行,但也可以使它延迟一段时间执行。这就要用到WaitForSecond:

IEnumerator Fade() {
    for (float f = 1f; f >= 0; f -= 0.1f) {
        Color c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
        yield return new WaitForSeconds(.1f);
    }
}

    它被常用于扩散一个效果并持续一段时间,它也是一种有用的优化手段。游戏中许多任务需要被定期执行,最好的方法就是把它们写进Update函数里。可是,一个函数通常在一秒中被调用很多次。当一个任务不需要被如此频繁地反复执行时,你能把它放进coroutine里,使它有规律地执行,而不是在每一帧中都执行。比如在游戏中,当敌人出现在玩家附近是,警报就会响起,代码可以这样写:

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);
    }
}

    这将大大减少执行检查的数量,而不会对游戏产生任何明显的影响。

© 著作权归作者所有

共有 人打赏支持
LIndieGS
粉丝 0
博文 9
码字总数 6421
作品 0
程序员
Java也可以有协同程序!

Java也能够像Lua一样拥有协同程序。你觉得不可能?其实可以用JavaX(一种Java源代码编译的Java方言)中实现! 目前,将一个函数转换为协同程序需要一点(直接的)源代码转换——当然这些转换...

鸟栖沙岩
2016/08/26
12
0
Coroutines & Yield 协同程序 & 中断

untiy中常用的方法: Coroutines & Yield 协同程序 & 中断 他的作用是这样的: 写游戏代码,往往最终需要代码为连续的事件.结果会像这样:: public class example : MonoBehaviour {private ...

安世博
2016/02/04
58
0
Kotlin 1.3 RC 版发布:迁移你的 coroutines 程序吧!

Kotlin 1.3 RC 版发布了,这是 1.3 的最新预览版和候选版,更新内容主要包含与新语言功能相关的关键错误修复,值得注意的变化包括: Ktor is wrapping up its API and looking forward to y...

局长
今天
0
0
Unity3D_c#脚本注意要点

Inherit from MonoBehaviour 继承自MonoBehaviour All behaviour scripts must inherit from MonoBehaviour (directly or indirectly). This happens automatically in Javascript, but mus......

Matrix4X4
2012/06/26
306
0
忘了RxJava:Kotlin Coroutines才是你需要的

原文地址:https://proandroiddev.com/forget-rxjava-kotlin-coroutines-are-all-you-need-part-1-2-4f62ecc4f99b 使用RxJava创建GithubApi的网络层的接口如下: 虽然Rxjava是一个功能强大的......

小菜鸟程序媛
08/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Flask 开发填坑

插件的选择: flask-security 真的是个鸡肋啊。自带的页面,好丑。还不如用flask-login来做呢。

pearma
16分钟前
0
0
讲述下 :LVM逻辑卷管理遇到的问题

LVM学习逻辑卷管理创建逻辑卷遇到的问题 1 实验环境 系统 内核 发行版本 CentOS 2.6.32-754.2.1.el6.x86_64 CentOS release 6.10 (Final) 由于是最小化安装没有xfs命令,yum安装如下包支持此...

linuxprobe16
51分钟前
0
0
day95-20180922-英语流利阅读-待学习

Hey Jude 半个世纪传唱不衰的背后故事 毛西 2018-09-22 1.今日导读 2004 年,The Beatles 被《滚石》杂志选为“历史上最伟大的 50 位流行音乐家的第一位”。这四名来自英国利物浦的男孩不仅对...

飞鱼说编程
58分钟前
1
0
OSChina 周六乱弹 —— 放假前期焦虑症晚期

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @andonny :分享Matteo的单曲《Panama》: 《Panama》- Matteo 手机党少年们想听歌,请使劲儿戳(这里) @新垣吉衣OSC :我发现只要去有小朋友...

小小编辑
今天
193
10
wait()被notify()后,接着执行wait()后面的语句

wait()被notify()后,接着执行wait()后面的语句

noteman
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部