协程(IEnumerator)的使用
来源:互联网 发布:淘宝军用防毒面具价格 编辑:程序博客网 时间:2024/05/19 13:57
在Unity中,并没有多线程的概念(体现在当使用多线程的时候,线程里面不可以出现任何unity的类或者结构体),但是unity本身封装了一个类似于多线程的开启另一段逻辑的方法:协同程序。协程跟线程很类似,都是另开一段逻辑,又跟主线程相互联系。但是不同之处也有很多,比如协程是程序员可控的,而线程是由CPU决定的;线程的关闭需要手动关闭,协程在程序结束以后,由unity垃圾回收机制清理。最大的体现就是协程是属于unity的,可以在unity随意使用。
协程是封装于Monobehaviour,但是却不由Monobehaviour控制,由GameObject控制处理。协程的调用是在LateUpdate后调用,遇到yield挂起,如果满足条件,将会执行yield下面的代码。可以在unityAPI中查看到这个执行顺序:
因此,协程有极大的优势:随开随关。那么利用协程就可以做到很多事情,一般是关于变化过程的功能,像计时器,特效等。
那么接下来谈谈协程是如何使用的,以及用协程可以做的功能。
1、协程的开启:
(1)通过名称开启
private void Start() { StartCoroutine("test");//这里名字要和协程的方法名一致 } IEnumerator test() { yield return null; }
(2)通过方法开启
private void Start() { StartCoroutine(test()); } IEnumerator test() { yield return null; }
使用名称开启的时候,一定要注意:这个协程没有参数,如果有参数,是不可以通过名称开启的,只能通过方法来开启。
2、协程的停止:
协程停止类似于开始协程,使用关键字StopCoroutine()。里面有两个参数,需要注意的是,如果你开启协程使用的是通过名称,那么停止也必须使用名称;反之,如果通过方法开启,也必须通过方法来停止。所以里面的参数不要填错就行。另外有一种方法是: StopAllCoroutines()。这个方法是立马停止类里面的所有协程。这两种方法是比较简单,只需要调用就行了。但是接下来介绍三种另外停止的方法:
(1)通过协程的返回值停止:
Coroutine coroutine; private void Start() { coroutine = StartCoroutine("test"); } IEnumerator test() { yield return null; }
开启协程的返回值是Coroutine,通过StopCoroutine(coroutine)也可以停止协程。原理就是类似于引用类型,将地址赋予一个变量。这是因为开启协程和变量在堆中指向的是同一个地址。
(2) 通过满足yield结束
协程是一种迭代器,遇到yield挂起,也就是等待的意思。那么方法执行结束后,协程就结束了。。但是在循环的时候,由于协程里的变量是与主线程相互联系的,那么与外部联系同样也可以结束协程。那么举个例子:
float checkTime = 0; private void Start() { StartCoroutine("test"); } private void Update() { if(Input.GetMouseButtonDown(0)) { checkTime = 101; } } IEnumerator test() { while(true) { if(checkTime <= 100) { checkTime += Time.deltaTime; yield return null; } else { yield break; } } }
yield break 跳出循环。如果不是放在循环里,那么就类似于方法中的return。
这个时候,如果我们按下鼠标左键,协程就不满足条件,那么跳出循环就结束了。所以通过这里可以看出,协程的字段与主线程,外部都有联系,通过外部修改,协程内部同样也能得到。
(3) 通过GameObject控制:
协程是封装于Monobehaviour中,但是不由Monobehaviour控制,体现在:
private void Start() { StartCoroutine("test"); enabled = false; } IEnumerator test() { yield return null; }
通过控制脚本,将enable设置为false,如果是在循环体中,这时候会发现协程并没有停止,依然在运行。
那么这个时候如果想控制不让协程运行,可以这么写
gameObject.SetActive(false);
由于协程是受gameobject控制,将gameobject设置为false,那么协程就会随即停止,这个时候再启用物体,协程是不会继续得。所以设置为false,协程是停止不是暂停。
不过不推荐这样使用,除非是要将物体禁用了。
使用协程需要注意:
(1)传递参数得时候是不能使用ref,out传递参数
(2)协程一定要有yield
(3)如果通过名称开启协程,这个协程一定是没有参数得。
(4)使用StopCoroutine停止协程得时候,要跟开启协程得时候保持一致,通过什么类型开启就通过什么类型关闭。
3、协程的运行时间
协程是在lateUpdate后处理,处理速度与方法的速度一致。 举个例子:
private void Start() { StartCoroutine("test"); print("Start"); } IEnumerator test() { print("test"); yield return null; }
这个时候在Start开始调用,那么打印就是先打印test,再打印Start。意思是都在这一帧调用,假如我们等待一帧:
private void Start() { StartCoroutine("test"); print("Start"); } IEnumerator test() { print("test"); yield return null; print("yield return null"); }
那么打印顺序就变成了先test,后Start,后yield return null。所以协程的处理速度也是方法的处理速度,在同一帧中,自上而下调用。相当于两条路的车速度一模一样。
4、yield 参数的大致了解:
yield是控制协程暂停,结束的迭代,在yield后有很多参数可以做到等待,就不做演示,就将参数解释一下:
yield return null; // 下一帧再执行后续代码 yield return 0; //这里不管填多少,都是等待一帧。如果要等待多少秒,用WaitForSeconds或者WaitForSecondsRealtime yield break; //跳出循环或者结束协程 yield return AsyncOperation;//等待异步操作 yield return WWW;//等待WWW加载完成 yield return new WaitForEndOfFrame();//等待所有的摄像机和GUI等被渲染完成 yield return new WaitForSeconds(1.5f);//等待1.5秒,这里单位是秒(注意:这里的时间是默认乘以Time.timeScale); yield return new WaitForSecondsRealtime(1.5f);//等待1.5秒,这里单位是秒(注意:这里的时间不乘Time.timeScale); yield return WaitForFixedUpdate();//等待下一帧FixedUpdate开始
如果想一起探讨技术,可以添加扣扣群:478462732。
不过首先声明:我是菜鸟。
阅读全文
1 0
- 协程(IEnumerator)的使用
- IEnumerator和IEnumerator接口的使用
- IEnumerable和IEnumerator的使用
- IEnumerator和IEnumerable是怎样使用的
- C#中的IEnumerable和 IEnumerator的使用
- 我眼中的协同(unity IEnumerator )
- IEnumerator 枚举使用
- 使用IEnumerator,IEnumerable接口制作一个简单的迭代器
- 使用 Hashtable(哈希表)和 IEnumerator 接口 示例
- Unity中IEnumerator协程
- IEnumerable和IEnumerator详解(IEnumerable的使用方法详解)
- 使用IEnumerable和IEnumerator接口
- IEnumerator和IEnumerable的关系
- IEnumerable和IEnumerator的理解
- IEnumerable和 IEnumerator的区别
- IEnumerator和IEnumerable的区别
- IEnumerator 协程 全称协同程序
- 「Unity3D」(6)协程使用IEnumerator的几种方式
- 人工智能、机器学习和深度学习三者的关系
- JMockit
- NoClassDefFoundError: javax/servlet/jsp/jstl/core/Config
- C#游戏开发基础03
- IOS UITabBar 隐藏分割线
- 协程(IEnumerator)的使用
- Warning: mysqli_query() expects parameter 1 to be mysqli, null given in /var/www/html/php..解决方案
- 冒泡排序(C语言)
- Java中的Atomic包使用指南
- Eclipse 修改字符集
- Date日期的一些操作
- javaSE知识点--01(01JDK安装与命令行编译方式概述)
- 【SSH网上商城】图片上传技术
- Centos7.x elastalert安装配置
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
黑母猪
小猪仔多少钱
杜洛克母猪
公猪价格
江苏猪苗
湖南猪苗
猪苗报价
云南苗猪价格
小猪预混料
猪价钱
河南猪崽价格
猪仔市场
小猪仔批发
猪苗价
猪仔鱼
广西那里有猪仔卖
片仔癀珍珠霜毁容害人
片仔癀珍珠霜
片仔癀一颗一年吃一次
皇后牌片仔癀珍珠膏
皇后牌片仔癀珍珠霜
皇后片仔癀珍珠膏
复方片仔癀软膏
2018片仔癀多少钱一粒
片仔癀护肤品
片仔癀牙膏
片仔癀股吧
皇后牌片仔癀珍珠霜怎么样
复方片仔癀含片
片仔癀祛痘
片仔癀化妆品怎样
片仔癀珍珠膏功效
片仔癀吃法
皇后片仔癀珍珠霜
片仔癀成分
片仔癀功效与用法
片仔癀胶囊
片仔癀软膏
片仔癀化妆品有激素
复方仔癀含片
片仔癀价格