文档章节

协同程序(Coroutines)

LIndieGS
 LIndieGS
发布于 2017/06/05 14:35
字数 804
阅读 2
收藏 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...

局长
09/22
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

没有更多内容

加载失败,请刷新页面

加载更多

ConcurrentHashMap 高并发性的实现机制

ConcurrentHashMap 的结构分析 为了更好的理解 ConcurrentHashMap 高并发的具体实现,让我们先探索它的结构模型。 ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEnt...

TonyStarkSir
今天
3
0
大数据教程(7.4)HDFS的java客户端API(流处理方式)

博主上一篇博客分享了namenode和datanode的工作原理,本章节将继前面的HDFS的java客户端简单API后深度讲述HDFS流处理API。 场景:博主前面的文章介绍过HDFS上存的大文件会成不同的块存储在不...

em_aaron
昨天
2
0
聊聊storm的window trigger

序 本文主要研究一下storm的window trigger WindowTridentProcessor.prepare storm-core-1.2.2-sources.jar!/org/apache/storm/trident/windowing/WindowTridentProcessor.java public v......

go4it
昨天
6
0
CentOS 生产环境配置

初始配置 对于一般配置来说,不需要安装 epel-release 仓库,本文主要在于希望跟随 RHEL 的配置流程,紧跟红帽公司对于服务器的配置说明。 # yum update 安装 centos-release-scl # yum ins...

clin003
昨天
9
0
GPON网络故障处理手册

导读 为了方便广大网络工作者工作需要,特搜集以下GPON网络处理流程供大家学习参考。开始—初步定为故障—检查光纤状况—检查ONU状态--检查设备运行状态—检查设备数据配置—检查上层设备状态...

问题终结者
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部