Unity中的协程理解
2020-07-04 本文已影响0人
能不写代码么

前言
- Unity中的协程经常会用到,可能大家也听过启动协程带来额外的开销成本大约是标准函数调用的三倍,还会分配一些内存,将当前状态存储在内存中,直到下一次调用它,因此要谨慎的使用。
- 禁用组件无法使初始化的协程停止:协程的运行独立于MonoBehaviour组件中Update()回调的触发,不管组件是否禁用,都将继续调用协程
- 禁用GameObject会停止协程:包含协程的GameObject变成不活动的那一刻自动停止,但是GameObject再次设置为活动时协程不会自动重启
- 处理性能优化:即由于在给定的帧中调用该方法的次数太多而导致帧率超出预算可以使用协程减少调用次数,减少帧中的性能损失
方法介绍
-
yield return new WaitForSeconds(time);
协程在yield语句上暂停指定的秒数,但是它不是一个精准的计时器,所以当这个yield语句上暂停指定的秒数,会有少量变化
而且要注意,会受到Time.timeScale 产生时间缩放,可以做慢动作效果
IEnumerator TestIEnumerator()
{
yield return new WaitForSeconds(3f);
}
-
yield return new WaitForSecondsRealtime(time);
协程在yield语句上暂停指定的秒数,但是它不是一个精准的计时器,所以当这个yield语句上暂停指定的秒数,会有少量变化
和WaitForSeconds的区别是:它使用的是未缩放的时间,不会受到Time.timeScale影响
IEnumerator TestIEnumerator()
{
yield return new WaitForSecondsRealtime(3f);
}
-
yield return new WaitForEndOfFrame();
延迟一帧,在下一个Update结束时继续
IEnumerator TestIEnumerator()
{
yield return new WaitForEndOfFrame();
}
-
yield return new WaitForFixedUpdate();
延迟一帧,在下一个FixedUpdate()结束时继续
IEnumerator TestIEnumerator()
{
yield return new WaitForFixedUpdate();
}
-
yield return new WaitUntil(委托)
在此函数中,提供了一个委托函数,协程根据给定的委托返回为 true 继续执行
需要注意,为这些yield类型提供的委托将对每个Update()后执行一次,直到返回停止它们需要的bool
using System.Collections;
using UnityEngine;
public class TestObb : MonoBehaviour
{
[SerializeField]
private float ieStart;
private void Start()
{
//开启协程
StartCoroutine(TestIEnumerator());
}
private void Update()
{
if(ieStart <= 10f)
{
ieStart += Time.deltaTime;
}
}
IEnumerator TestIEnumerator()
{
Debug.LogError("Start TestIEnumerator");
//当计时器达到 10s 继续执行协程
yield return new WaitUntil(() => ieStart >= 10f);
Debug.LogError("End TestIEnumerator");
}
}
-
yield return new WaitWhile(委托)
和WaitUntil相反,协程根据给定的委托返回为 false 继续执行
using System.Collections;
using UnityEngine;
public class TestObb : MonoBehaviour
{
[SerializeField]
private float ieStart;
private void Start()
{
//开启协程
StartCoroutine(TestIEnumerator());
}
private void Update()
{
if(ieStart <= 10f)
{
ieStart += Time.deltaTime;
}
}
IEnumerator TestIEnumerator()
{
Debug.LogError("Start TestIEnumerator");
//当计时器达到10s继续执行协程 , ieStart<10为 false
yield return new WaitWhile(() => ieStart < 10f);
Debug.LogError("End TestIEnumerator");
}
}