Unity3D Coroutine嵌套问题 以原始的方式停止嵌套协程

版权声明:本文为博主原创文章,未经博主允许不得转载。 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或者最原始的名称停止方式,因为无法获取到里层的协程。

 

当然大家完全可以自己实现一套协程的运行方式,所以的控制都在自己这边这类问题都是小事。但是总归在很多项目中,用了原始的协程,想要改成自己写的协程方式不仅工作量大、还需要和项目组做一些沟通,这个时候就可以使用上面的代码了。

猜你喜欢

转载自blog.csdn.net/u012632851/article/details/82939686