深入探讨Unity协程及其使用

协程

协程在Unity中是个很重要的东东,相信很多人都使用过,它能够非常方便的进行异步等待操作,可以说,用好协程,可以使你的代码更加优雅,然而,如果用不好,代码就会有变成翔的可能,甚至已经变成了翔,你自己居然还不知道。那么,我们就来好好聊聊协程吧。

协程的本质

协程并不是Unity创造的,它本来就存在于C#。协程的本质是迭代器,通过调用MoveNext(),直到迭代结束。
通过下面的代码,可以清晰的看到他的工作原理:

static IEnumerator<int> MyCoroutine()
{yield return 0;yield return 1;for( int i = 2; i < 10; ++ i )yield return i;
}static void Main(string[] args)
{var mc = MyCoroutine();while( mc.MoveNext()){Console.WriteLine( mc.Current );}Console.ReadKey();
}

在Unity的游戏循环中,每次循环或者说每帧都会去调用MoveNext(),于是看起来,协程“并行”了。然而,协程并不是线程,它本质并不是并发的。

协程带来的问题

请看下面的例子:
public float speed = 0.5f / 1f;
CanvasGroup group;private void Start()
{group = GetComponenet<CanvasGroup>();
}public void Show()
{StartCoroutine(_show());
}public void Hide()
{StartCoroutine(_hide());
}private IEnumerator _show()
{while( group.Alpha < 0.999 )group.Alpha += speed * Time.deltaTime;group.Alpha = 1;
}private IEnumerator _hide()
{while( group.Alpha > 0.001 )group.Alpha -= speed * Time.deltaTime;group.Alpha = 0;
}

上面的例子中,实现了一个UI的渐隐和渐现功能,一般情况下,它能很好的工作。当你调用了Show(),他会渐现,当你调用了Hide(),他会渐隐。然而,它潜在的问题是,如果你调用了Show(),渐现到一半时(_show协程未结束),接着调用Hide(),那么两个协程将同时运行,一个负责增加group.Alpha,另一个负责减少group.Alpha,导致group.Alpha始终不会高于0.999,也始终不会低于0.001,界面就卡在那里了。
那么为了保证每次只有一个协程在运行,你可能会这么改:

public void Show()
{StopAllCoroutine();StartCoroutine(_show());
}public void Hide()
{StopAllCoroutine();StartCoroutine(_hide());
}

虽然通过加一个StopAllCoroutine()能解决上面的问题,但最起码,它已经不怎么“优雅”了。更优雅的实现同样功能,应该考虑使用状态机,而不是协程。

再来看一个例子:



这是unity官方在B站发布的视频,他的大意是:第一,协程是语法糖,他本质上是一个状态机,加上一堆goto语句。第二,也是最重要的,不要让一个协程永远不退出,就是不要有上图例子中的while(true)这样的协程,他强烈不建议这么用,因为这样可能会有内存问题。有兴趣的可以去看看原视频——“豆知识 匿名类”。

到底应该什么时候用协程

使用协程应该满足“FIRE AND FORGET”原则,即“点火后忘记”原则。就是说,只需要发起它,而不用管它后续的情况(不需要时刻记得它),就可以使用协程。比如说,发起一个资源下载,然后等他出来结果。

另外,协程只工作在主线程,他只是循环的被调用,本身并不能解决并发的问题,所以,如果你想要并发,请使用多线程。

白猫,黑猫,抓到老鼠就是好猫,总之,没有绝对的好于坏,具体需求要具体分析,协程也好,线程也罢,各有各的优缺点,只要能实现功能需求,达到性能要求,就是好的,但这就需要我们深入的去理解功能点,分析需求逻辑。

深入探讨Unity协程及其使用相关推荐

  1. Unity 协程Coroutine综合测试

    Unity 协程Coroutine综合测试 1 using UnityEngine; 2 using System.Collections; 3 using System.Text; 4 5 publ ...

  2. Unity协程(Coroutine)原理深入剖析再续

    Unity协程(Coroutine)原理深入剖析再续 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面已经介绍过对协程(Coroutine ...

  3. Unity 协程深入解析与原理

    先来直接放一段代码 1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 p ...

  4. Unity协程实现分析以及Lua协程与Unity协程的混合使用

    1,节选翻译一篇stackoverflow关于Unity协程实现的讨论 - The big clues are in the C# version. Firstly, note that the re ...

  5. Unity协程(Coroutine)原理深入剖析

    Unity协程(Coroutine)原理深入剖析 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 记得去年6月份刚开始实习的时候,当时要我写网 ...

  6. Unity(协程是什么,怎么用)

    c#协程 概:早就听闻Unity协程有必要学一手,但我还是搁置了好久,直到这个搓东西的时候被迫用了多线程发现解决不了,百度一手得知我不得不学一下协程了.在搜集了一些资料后发现知乎大佬的博文香的一批(我 ...

  7. Unity协程实现场景中鼠标按住的物体跟随鼠标移动

    Unity协程实现场景中的鼠标按住物体跟随鼠标移动 void Awake() { StartCoroutine(OnMouseDown() as IEnumerator); } IEnumerator ...

  8. unity 协程特点

    协程 一. Unity中使用协程 1. 什么是协程 2. 如何使用 3. 协程的应用场景 创建补间动画 打字机效果 异步加载资源 4. 注意事项 二. Unity协程的底层原理 1. 协程本体:C#的 ...

  9. Unity协程那些事儿

    Unity协程那些事儿 1.什么是协程? 2.协程的使用 3.关于yield 4.关于IEnumerator/IEnumerable 5.从IEnumerator/IEnumerable到yield ...

最新文章

  1. 青岛市教师职称计算机考试成绩查询系统,吴春雷
  2. TencentOCR 斩获 ICDAR 2021 三项冠军
  3. 2016 校园招聘求职经历(二)
  4. 商务搜索引擎_2019年中国网民搜索引擎使用情况研究报告
  5. simulink显示多个数据_Matlab/Simulink与自动驾驶(ADAS)算法开发
  6. 这才是真正的用户增长
  7. C/C++好不好学习呢?
  8. IO流——字节流、字符流
  9. Android -- Property Animation
  10. 部署Webpart的方法
  11. spring boot服务部署后访问zul页面404
  12. 电影mysql设计_电影院数据库设计(案例)
  13. 人大金仓数据库 Windows安装教程 -kingbase8R6
  14. ddr4单颗粒最大_国产内存来了:长鑫发布DDR4/LPDDR4X内存
  15. 字节跳动移动架构师学习笔记,Android篇
  16. 全民创业时代,拥有一项技能就能当老板?
  17. 会员营销中,数字会员模式如何打造差异化会员服务
  18. 西方投资组合理论及其新发展综述
  19. python自动测试优惠券过期_python逻辑回归模型-使用优惠券预测
  20. server 2008 R2 server_2008_r2服务器下载

热门文章

  1. linux命令--文件夹重命名
  2. 彻底掌握 Commonjs 和 Es Module
  3. ES Module在nodeJS下与CommonJS的交互
  4. VM 虚拟机网络配置
  5. CardView使用详解
  6. Diffusion模型详解
  7. Android ListView添加头部和尾部
  8. 推荐系统[九]项目技术细节讲解z4:向量检索技术工程上实践,曝光去重实践以及检索引擎该如何选择:支撑亿级索引、5毫秒级的检索[elasticsearch、milvus]
  9. CSS实现背景图片不规则的导航菜单
  10. Java中BIO,NIO,AIO