协程(一)基本使用
协程(二)协程什么时候调用
协程(三)IEnumerable、IEnumerator、foreach、迭代
协程(四)yield与迭代器
协程(五)简单模拟协程
协程(六)有关优化
参考官方:https://docs.unity3d.com/Manual/Coroutines.html
一. 为什么使用协程
1. 基本功能和使用
- 当你调用一个函数时,它会在函数返回之前将代码全部运行完成。这实际上意味着在函数中发生的任何动作都是在单帧更新中发生。
- 函数调用不能用于:类似于动画的程序或依靠时间变化的事件。
- 例如,考虑逐渐减少对象的alpha(不透明度)值直到它变得完全不可见的任务。
void Fade()
{
for (float ft = 1f; ft >= 0; ft -= 0.1f)
{
Color c = renderer.material.color;
c.a = ft;
renderer.material.color = c;
}
}
- 但是你看不到它中间值的变化,于是你可以使用协程:
IEnumerator Fade()
{
for (float ft = 1f; ft >= 0; ft -= 0.1f)
{
Color c = renderer.material.color;
c.a = ft;
renderer.material.color = c;
yield return null;
}
}
- 它本质上是一个用返回类型IEnumerator声明的函数,并且在某个地方伴随一个yield return语句。yield return null 是执行暂停并在下一帧继续执行下面代码的点。
- 当然你需要使用这个开启协程
void Update()
{
if (Input.GetKeyDown("f"))
{
StartCoroutine("Fade");
}
}
- 默认情况下,协程在生成后会在帧上恢复,但也可以使用WaitForSeconds引入时间延迟:
IEnumerator Fade()
{
for (float ft = 1f; ft >= 0; ft -= 0.1f)
{
Color c = renderer.material.color;
c.a = ft;
renderer.material.color = c;
yield return new WaitForSeconds(.1f);
}
}
2.使用理由一
- 上面的代码,你确实可以用标志位实现,不过不太好用。
void Update(){
if(isStart){
Fade();
isStart = false;
}
}
3.使用理由二
- 当任务不需要经常重复时,您可以将它放在协程中以定期更新,但不是每一帧。这方面的一个例子可能是警报,如果敌人在附近就会警告玩家。
function ProximityCheck()
{
for (int i = 0; i < enemies.Length; i++)
{
if (Vector3.Distance(transform.position, enemies[i].transform.position) < dangerDistance)
{
return true;
}
}
return false;
}
- 如果有很多敌人,那么每帧调用此函数可能会带来很大的开销。但是,您可以使用协程每十分之一秒调用一次:
IEnumerator DoCheck()
{
for(;;)
{
ProximityCheck();
yield return new WaitForSeconds(.1f);
}
}
- 这将大大减少执行的检查次数,而不会对游戏玩法产生任何明显影响。
二.注意事项
- 禁用MonoBehaviour时,协程不会停止。
- 只有当它被明确销毁时才会停止。
- 你可以使用MonoBehaviour.StopCoroutine和MonoBehaviour.StopAllCoroutines来停止。
- 当MonoBehaviour被破坏、或它连接的游戏对象被禁用,协程会停止。
网友评论