协程知识点
什么是协同程序?
协程并不是多线程的,只是在同一个线程中开辟了一段代码块
主要要注意的地方,协程的开启,和yield
return
的使用
在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足。
1、要弄清楚携程首先得弄清楚生命周期函数,在unity中的生命周期函数
Awake()
:唤醒事件,游戏一开始运行就执行,只执行一次
OnEnable()
:启用事件,只执行一次。当脚本组件被启用时执行一次
Start()
:开始事件,执行一次
FixedUpdate()
:固定更新事件,执行N次,0.02s
执行一次。所有的物理组件相关更新都在这个事件中处理。
Update()
:更新事件,执行N次,每帧执行一次。
LateUpdate()
:稍后更新事件,执行N次,在update()事件执行完毕后再执行。
OnGUI()
:GUI渲染事件,执行N次,执行的次数是Update()事件的两倍。
OnDisable()
:禁用事件,执行一次。在OnDestroy()
事件前执行。或者当该脚本组件被禁用后,也会触发该事件。
OnDestory
():销毁事件,执行一次。当脚本所挂载的游戏物体被销毁时执行。
2、协程的开启方式
开启线程有两种方式,一种是用的携程函数的返回值,一种是通过函数名称字符串
第一种方式可以带任意数量的参数,第二种最多只能带一个参数
//Coroutine 协程
//StartCoroutine 可以通过函数名称字符串或者协程函数的返回值来启动协程
StartCoroutine(Print());
UnityEngine.Coroutine coroutine = StartCoroutine(CreatEnemy(value));
//通过函数的返回值启动的协程,可以带有任意数量的参数,但使用字符串启动的协程只能带有一个参数或不带参数
StartCoroutine("CreatEnemy");
StartCoroutine("CreatEnemy", value);
3、协程的关闭方式
使用字符串启动的协程可以通过StopCoroutine
方法停止,但是使用返回值启动的协程不能通过StopCoroutine
用函数名来停止,但可以停止单独的coroutine对象
//所有的协程都可以通过 StopAllCorourtines
来停止
如果想停止多个协程,可使用StopAllCoroutines
方法,但这种方法只能停止当前MonoBehaviour
类实例中所有协程.其他不受影响.
如果想停止gameObject
上所有脚本组件中的协程,禁用脚本组件是无法停止协程的,只需要禁用gameObject
即可.
StopCoroutine("CreatEnemy");
IEnumerator cor;
cor = CreatEnemy();
StartCoroutine(cor);
StopCoroutine(cor);
StopAllCorourtines();
4、协程的等待方式
yield null:返回null或任意数值,会在下一帧的update调用后执行
yield WaitForSeconds:协程在延迟指定时间,且当前帧所有脚本的 Update全都执行结束后才继续执行.
yield WaitForFixedUpdate:协程在所有脚本的FixedUpdate执行之后,再继续执行.
yield WWW:协程在WWW下载资源完成后,再继续执行.
yield StartCoroutine:协程在指定协程执行结束后,再继续执行.
WaitForSecondsRealtime:与WaitForSeconds类似,但不受时间缩放影响.
WaitWhile:当返回条件为假时才执行后续步骤.
WaitFromEndOfFrame:在渲染结束后进行调用,调用在onDrawGizmos和OnGUI之后,只比OnDisable早
yield return null; // 下一帧再执行后续代码
yield return 0; //下一帧再执行后续代码
yield return 6;//(任意数字) 下一帧再执行后续代码
yield break; //直接结束该协程的后续操作
yield return asyncOperation;//等异步操作结束后再执行后续代码
yield return StartCoroution(/*某个协程*/);//等待某个协程执行完毕后再执行后续代码
yield return WWW();//等待WWW操作完成后再执行后续代码
yield return new WaitForEndOfFrame();//等待帧结束,等待直到所有的摄像机和GUI被渲染完成后,在该帧显示在屏幕之前执行
yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间会受到Time.timeScale的影响);
yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的时间延迟之后继续执行,在所有的Update函数完成调用的那一帧之后(这里的时间不受到Time.timeScale的影响);
yield return WaitForFixedUpdate();//等待下一次FixedUpdate开始时再执行后续代码;
yield return new WaitUntil()//将协同执行直到 当输入的参数(或者委托)为true的时候....如:yield return new WaitUntil(() => frame >= 10);
yield return new WaitWhile()//将协同执行直到 当输入的参数(或者委托)为false的时候.... 如:yield return new WaitWhile(() => frame < 10);
6、使用过的地方
分拨次生成怪物
每过1s
生成一个小怪,每生成5个小怪,生成一个大怪,每15s
执行一次
IEnumerator CreatEnemy()
{
while (true)
{
for (int i = 0; i < 5; i++)
{
Debug.Log("小怪");
yield return new WaitForSeconds(1);
}
Debug.Log("大怪");
yield return new WaitForSeconds(15);
}
}