U2L7——协同程序
U2L7——协同程序
协同程序
协同程序简称协程,它是“假”的多线程,它不是多线程
它的主要作用:
将代码分时执行,不卡主线程
简单理解,是把可以会让主线程卡顿的耗时的逻辑分时分步执行
主要使用场景:
异步加载文件,异步下载文件,场景异步加载,批量创建时防止卡顿
Unity支持多线程,只是新开线程无法访问主线程中Unity相关内容
一般主要用于进行复杂逻辑运算或者网络消息接收等等
注意:Unity中的多线程一定要记得关闭!!!
对于协程的原理,请看协同程序原理
总结:
协同程序(协程)不是多线程,它是将线程中逻辑进行分时执行,避免卡顿,继承MonoBehaviour
的类都可以使用协程
协程只有当组件单独失活时不受影响 其他情况下协程会停止
这个属于MonoBehaviour
基类的重要方法,之前的重要方法看这里 -> MonoBehaviour
本章代码关键字
1 | IEnumerator //本质实现是迭代器所需的接口,在这里只有返回值为该接口的函数,才能成为协程的函数 |
Unity是否支持多线程
首先明确,Unity支持多线程
但是新开线程无法访问Unity对象相关的内容
多线程的意义在于,可以将复杂逻辑的计算放进多线程的计算
注意:Unity中的多线程 要记住关闭(不关闭会导致线程与编辑器共生)
1 | t = new Thread(Test); |
协同程序和线程的区别
新开一个线程是独立一个管道,和主线程并行执行
新开一个协程是在原线程之上开启,进行逻辑分时分步执行
协程的使用
继承MonoBehaviour
的类 都可以开启 协程函数
声明协程函数
协程函数有两个关键点
- 返回值为
IEnumerator
类型及其子类 - 函数中通过
yield return 返回值;
进行返回
1 | //关键点一:协同程序(协程)函数 返回值 必须是 IEnumerator或者继承它的类型 |
开启协程函数
协程函数是不能这样直接执行的!!!这样执行没有任何效果:MyCoroutine(1, "123");
常用开启方式:
1 | Coroutine c1 = StartCoroutine(MyCoroutine(1, "123")); |
或者这样开启
1 | IEnumerator ie = MyCoroutine(1, "123"); |
关闭协程
关闭所有协程
会停止自己类里所有还在执行的协程(不影响其它类的协程)
1 | StopAllCoroutines(); //会停止自己类里所有还在执行的协程(不影响其它类的协程) |
关闭指定协程
1 | StopCoroutine(c1); //用协程变量来指定关闭其中存放的协程 |
yield return
yield return
是函数的分界点,n个yield return
就把函数分为n+1个部分
遇到yield return
就会将函数挂起,根据yield return
后面的内容来决定什么时候再开始执行
可以在协程内写死循环,让协程被分为无数步,这样不会卡死程序
下一帧或者等待指定帧后执行
在Update
和LateUpdate
之间执行
1 | yield return 数字; |
等待指定秒后执行
在Update
和LateUpdate
之间执行,它受 Time.timeScale 影响
1 | yield return new WaitForSeconds(秒数); |
等待下一个固定物理帧更新时执行
在FixedUpdate
和碰撞检测相关函数之后执行
1 | yield return new WaitForFixedUpdate(); |
等待摄像机和GUI渲染完成后执行
在LateUpdate
之后的渲染相关处理完毕后之后
1 | yield return new WaitForEndOfFrame(); |
一些特殊类型的对象 比如异步加载相关函数返回的对象
之后讲解 异步加载资源 异步加载场景 网络加载时再讲解
一般在Update
和LateUpdate
之间执行
跳出协程
1 | yield break; |
不受Time.timeScale
影响的等待指定秒后执行
在Update
和LateUpdate
之间执行,顾名思义,相对于yield return new WaitForSeconds(),它不受 Time.timeScale 影响
1 | yield return new WaitForSecondsRealtime(); |
协程受对象和组件失活销毁的影响
协程开始后:
- 组件或者物体销毁,协程无法执行
- 物体失活协程不执行,组件失活协程执行
关于Unity协程内的泛型方法
C# 的泛型方法,一定要传型参调用,因为这是编译检查的规划。不然编译就通不过。但unity的协程中就有例外呢?
Unity 的协程是特定于 Unity 引擎的功能,与 C# 泛型方法的编译时类型检查是不同的概念。在其他 C# 应用程序中,需要遵循泛型方法的规则。
1 | using System.Collections; |