版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012632851/article/details/82939686
环境:Unity2017.2 语言:C#
总起:
在使用协程的时候大家有没有遇到这样的问题?
因为协程之间可以相互嵌套,所以为了保证程序的清晰,便在其中添加了大量的嵌套代码,但是在想要停止协程的时候傻眼了,MonoBehaviour的StopCoroutine函数只能停止最外层的协程,如果正在执行里层的协程,必须等待里层的协程执行完毕(如果里层有while循环,那协程就永远不会停止了)。
以下是问题的代码:
private IEnumerator corDis;
void Awake()
{
corDis = Cor1();
StartCoroutine(corDis);
}
IEnumerator Cor1()
{
Debug.Log(1);
yield return new WaitForSeconds(2f);
Debug.Log(2);
yield return Cor11();
Debug.Log(3);
yield return new WaitForSeconds(4f);
Debug.Log(4);
}
IEnumerator Cor11()
{
Debug.Log(11);
yield return new WaitForSeconds(2f);
Debug.Log(22);
this.StopCoroutine(corDis);
Debug.Log(33);
yield return new WaitForSeconds(4f);
Debug.Log(44);
}
我们期望的是打印完33之后,程序就应该停止了,但是44仍会打印:
解决方案:
这边为MonoBehaviour添加了一个扩展方法,如下:
public static class UnityExtension
{
public static void StopCoroutineNested(this MonoBehaviour mono, IEnumerator ie)
{
var cur = ie;
mono.StopCoroutine(cur);
while (cur.Current is IEnumerator)
{
cur = cur.Current as IEnumerator;
mono.StopCoroutine(cur);
}
}
}
然后将this.StopCoroutine改为this.StopCoroutineNested就可以了:
这边有两个细节:
1.在使用扩展方法的时候,this不能省略;
2.停止的时候需要使用IEnumerator来停止,而不能使用Coroutine或者最原始的名称停止方式,因为无法获取到里层的协程。
当然大家完全可以自己实现一套协程的运行方式,所以的控制都在自己这边这类问题都是小事。但是总归在很多项目中,用了原始的协程,想要改成自己写的协程方式不仅工作量大、还需要和项目组做一些沟通,这个时候就可以使用上面的代码了。