关于Unity3D协程的使用

开辟线程的方法在Unity里面不是非常好使,如果需要做一些异步操作官方是提供了协程来处理的,但是官方的协程文档写的和没有写一样,这里我想强烈吐槽下...

不方便截图,给官方的协程文档网址。里面只告诉怎么用void StartCoroutine(string methodName,object param=null)这个接口的方法,这个方法简单粗暴,直接用函数名字就可以调用那个协程方法了,呵呵.....然而这样坑爹的问题就来了,我之后需要扩展下这个函数,或者别人需要拓展下,然后可能这个函数名也变了....然后编译下,嗯~没有报错,nice,提交上传.....然后过了几天,就发现你写的这个功能死活没用,你觉得不对啊,我就加了几行新的代码而已,没有改变之前的结构,运行也没有报错!!!到底错在哪里...这就是StartCoroutine("XXX")神秘的地方,即使你函数名不对它也不报错 。。(不过还好,新版的我测试了下是有这个找不到协程提示的)。而且在你重构代码的时候,用vs重构函数命名,StartCoroutine里面调用如果是字符串的话,是不会随着重构的,改起来超麻烦,你还要去改StopCoroutine的地方,而且看代码时候想跳转到函数声明的时候,需要你搜索文档去找了....我是极度不推荐这样使用协程的。

然后还剩下一个接口了Coroutine StartCoroutine(IEnumerator routine)可以用了,这个貌似很靠谱,然后停止的接口也非常漂亮的一目了然,就知道怎么用了void StopCoroutine(IEnumerator routine) ,果然还是有编程经验一看就懂,嘿嘿嘿....肯定是先用变量存下StartCoroutine抛出的Coroutine,然后需要停止的时候 就把这个变量丢给StopCoroutine里面去,嗯~~应该是这样,然后写了个测试例子:

using UnityEngine;
using System.Collections;

public class TestCoroutine : MonoBehaviour {
    IEnumerator Start () {
        Coroutine routine =StartCoroutine(CoroutineForever());
	yield return new WaitForSeconds(5);
        StopCoroutine(routine);
    }
    
    private IEnumerator CoroutineForever(){
        while(true){
            yield return new WaitForSeconds(1);
            print("Test Coroutine");
        }
    }
}
短短几行代码就实现了异步的每秒输出一个“Test Coroutine” 然后在五秒后停止的例子,协程真实方便啊....

然而惊奇的发现这个例子,在Unity4的版本里面,是不会被停止的!!!刚刚写的时候跑在Unity5里面居然停止了,应该是Unity也发现了...不然返回的这个Coroutine类型对象毫无意义...

然后再贴个靠谱的方法,在 Unity4和Unity5里面都非常好使的,而且方便协程的管理,再也不要用什么函数名了,恨死这东西了,Invoke也是:

using UnityEngine;
using System.Collections;

public class TestCoroutine : MonoBehaviour {

    IEnumerator Start () {
        IEnumerator routine =CoroutineForever();
        StartCoroutine(routine);
	yield return new WaitForSeconds(5);
        StopCoroutine(routine);
    }
    
    private IEnumerator CoroutineForever(){
        while(true){
            yield return new WaitForSeconds(1);
            print("Test Coroutine");
        }
    }
}
还好,只多了一行代码..

还有提醒下,如果是用StartCoroutine("XXX")的方式调用协程的话,千万一定要记得用StopCoroutine("XXX")的这个对应停止协程,StopCoroutine(IEnumerator routine)是停止不掉的。

另外还有在Unity4里面如果使用了协程的话一定要做管理,因为Unity4的MonoBehavior类没有对协程进行管理,因此在Destroy这个gameobject后,协程还是会被继续执行的,直到这个类被gc掉,所以需要写对协程管理的方法在OnDestroy里面,如果是对象池的话,需要在放入缓存池的时候把协程进行管理,如果不这样做,有可能你在协程里面尝试访问修改一些对象属性,被Destroy后对象属性访问是会报错的,所以所以....千万记得要管理好协程。不过还好Unity5里面已经内部做好这些管理工作了,在对象销毁后,所有协程也会被停止掉,但是如果做的是对象池,还是得老老实实做好协程管理。


你可能感兴趣的:(Unity3D,协程)