http://blog.csdn.net/narutojzm1/article/details/50255051
我先亮出我用的有关协程的代码:
既然是加载,那么加载就需要耗费时间,于是这里使用了协程,以保证图片加载完成后,再把图片赋值给mainTexture;
第一步:
在Button的响应中使用
StartCoroutine(loadNetWork())启动一个协程程序.
关于StartCoroutine
1.这个函数的参数,必须是一个返回值为IEnumerator类型的函数。
2.StartCoroutine不是启动了一个新的线程,而是开启一个协同程序,默认unity所有代码都在一个线程中
第二部:
执行loadNetWork函数
我把网断了,然后我发现程序在执行完yield return date后,很长时间没有反应,然后弹出了错误,说的是网络有问题访问不到之类的。
我把yield return date, 改成了yield return null;结果是,程序执行下一句了,不过下一句告知纹理还没有获取到,请使用isDone判断是否加载完成再执行(you are trying to load data from a www stream which has not completed the download yet.You need to yield the download or wait until isDone returns true)
那他既然让我使用isDone那我就使用呗,如下:
然后我发现我打印的进度一直在增长,最后就加载OK了!
于是我想当然的认为下面这种方式也可以,只要s够成:
于是我合理推测,如果是yield return date, 其中我返回的这个date,程序绝对做了处理,也就是说他们认识这个www类型,然后会帮忙进行加载,加载完毕后,才返回。而如果是null,或者wait之类的,由于程序没有得到date,也就没法特殊处理了,所以只有等得够久才有收获。
现在我对上面这段函数解释一番:
这个函数关键的就是这么几句话:1)创建WWW对象加载资源
这个资源的加载是个异步的过程,也就是说new WWW(...)执行完了之后,不用等待加载结果,直接执行下一句。正因为是异步的过程,所以才有了下面一行代码;
2)循环判断date.isDone是否为true,如果为true,则说明资源加载完毕,可以执行纹理赋值贴图过程。
3)如果资源未加载完毕,则执行yield return null。
关键就是解释这一句,我之前两年C#编程工作并没有接触到这个东西,这次看到后,感叹一句:这是个什么神马?!
一句话说就是:yield,用于创建生成器,执行时中断返回迭代器值,并记录现场,下次从现场处继续执行。
这里有两点: 1.Q:这句话的“下次”是啥时候?
A:这个总的来说,应该是下一帧,应该是Update执行后。有一个图可以参考一下:
2.Q:返回的值干什么用?
A:返回的值有很多类型,我引用下面这段来解释:
Unity官方文档对coroutine的解释:
Normal coroutine updates are run after theUpdate function returns. Acoroutine is a function that can suspend its execution (yield) until the givenYieldInstruction finishes. Different uses of Coroutines:
yield; The coroutine will continue after all Update functionshave been calledon the next frame.
yield WaitForSeconds(2); Continueafter a specified time delay, after all Update functions have been called for theframe.
yield WaitForFixedUpdate(); Continue afterall FixedUpdate has been called on all scripts.
yield WWWContinue aftera WWW download has completed
yield StartCoroutine(MyFunc); Chains the coroutine, and will wait for the MyFunc coroutine to completefirst.
C#要在yield coroutine之间加上return关键字。
看吧,上面这段文字完美的解释了我关于www的疑问,果不其然,yield有这么几种返回类型,其中WWWContinue的用法就是当下载完毕才会返回的,我也找到了另一处对返回值类型的说明,感觉描述不一样,但是意思一样,当个补充吧,如下:
WWW - after Updates happen for all game objects; check the isDone flag. If true, call the IEnumerator's MoveNext() function;
WaitForSeconds - after Updates happen for all game objects; check if the time has elapsed, if it has, call MoveNext();
null or some unknown value - after Updates happen for all game objects; Call MoveNext();
WaitForEndOfFrame - after Render happens for all cameras; Call MoveNext().
我单独翻译一下第一条:WWW-当该脚本绑定的所有游戏对象的Update函数执行完毕后发生,检查WWW这个返回值的isDone属性,如果这个属性为true,则调用枚举器的MoveNext函数(这也就意味着,一次yield的过程完成了,可以执行下一句了,当然如果没有下一句了,moveNext就会返回false,这个枚举过程就全部结束喽)
我这篇文章也只是记录了我的一些研究过程中的问题,只是协程整个解释中的极小一部分,我在研究过程中共参考了这么三篇文章,我觉得很值得一读,读的顺序就可以按照我的下面的顺序读
【Unity3D中的Coroutine详解】
http://blog.csdn.net/blues1021/article/details/40959915
这个里边简单例子多,更通俗些,关键还有个关于WWW类使用协程的封装,特别好
【简要分析unity3d中剪不断理还乱的yield】
http://blog.csdn.net/huang9012/article/details/29595747
这个主要是有一些更丰满的例子,比如关于在对话框中逐个显示文字啦之类的,还有个对协程原理分析的摘要,也很到位
【Unity协程(Coroutine)原理深入剖析再续】
http://www.manew.com/blog-53680-2637.html
这个最后读吧,因为确实讲的比较深,连关于协程的代码实现也罗列了,让人看完更清楚了