StartCoroutine就是开启一个协程.
yield return 保存函数状态,迭代器块返回调用迭代的地方。等待下次调用继续从当前位置处理。
- 可以使用 StopCoroutine 和 StopAllCoroutines 来停止协程。 当用 SetActive(false) 禁用某个协程所附加到的游戏对象时,该协程也将停止。调用 Destroy(example)(其中 example 是一个 MonoBehaviour 实例)会立即触发 OnDisable,并会处理协程,从而有效地停止协程。最后,在帧的末尾调用 OnDestroy。
- 通过在 MonoBehaviour 实例上将 enabled 设置为 false 来禁用 MonoBehaviour 时,协程不会停止。
调用函数时,函数将运行到完成状态,然后返回。这实际上意味着在函数中发生的任何动作都必须在单帧更新内发生;函数调用不能用于包含程序性动画或随时间推移的一系列事件。例如,假设需要逐渐减少对象的 Alpha(不透明度)值,直至对象变得完全不可见。
协程就像一个函数,能够暂停执行并将控制权返还给 Unity,然后在下一帧继续执行。在 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 行是暂停执行并随后在下一帧恢复的点。要将协程设置为运行状态,必须使用 StartCoroutine 函数:
void Update()
{
if (Input.GetKeyDown("f"))
{
StartCoroutine("Fade");
}
}
您会注意到 Fade 函数中的循环计数器能够在协程的生命周期内保持正确值。实际上,在 yield 语句之间可以正确保留任何变量或参数。
默认情况下,协程将在执行 yield 后的帧上恢复,但也可以使用 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);
}
}
在附近有敌人时向玩家发出的警报,每十分之一秒调用一次:
IEnumerator DoCheck()
{
for(;;)
{
ProximityCheck();
yield return new WaitForSeconds(.1f);
}
}
function ProximityCheck()
{
for (int i = 0; i < enemies.Length; i++)
{
if (Vector3.Distance(transform.position, enemies[i].transform.position) < dangerDistance) {
return true;
}
}
return false;
}
如果你在语句中使用 yield 上下文关键字,则意味着有它出现的方法、运算符或 get 访问器是迭代器。
在为自定义集合类型实现IEnumerable和IEnumerator模式时,使用yield定义迭代器就不需要显式的额外类(包含枚举状态的类,请参阅IEnumerator )。
yield return <expression>;
yield break;
一个协程的执行可以在任何地方用yield语句来暂停,yield return的值决定了什么时候协程恢复执行。
yield return的值 | 含义 |
---|---|
yield return null; | 暂停协同程序,下一帧再继续往下执行 |
yield new WaitForFixedUpdate (); | 暂停协同程序,等到下一次调用FixedUpdate方法时再继续往下执行 |
yield return new WaitForSeconds(2); | 暂停协同程序,2秒之后再继续往下执行 |
yield return StartCoroutine(“SomeCortoutineMethod”); | 暂停此协同程序,开启SomeCortoutineMethod协同程序,直到SomeCortoutineMethod执行完再继续往下执行。SomeCortoutineMethod用yield暂停不算执行完。 |