Unity 协程Coroutine综合测试
生活随笔
收集整理的這篇文章主要介紹了
Unity 协程Coroutine综合测试
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Unity 協(xié)程Coroutine綜合測(cè)試
1 using UnityEngine; 2 using System.Collections; 3 using System.Text; 4 5 public class rotCube : MonoBehaviour { 6 7 //示例,如何為一個(gè)自定義對(duì)象實(shí)現(xiàn)GetEnumerator接口,從而可以對(duì)該對(duì)象使用foreach 8 //這種寫(xiě)法是c#2.0才有的,通過(guò)yield關(guān)鍵字與IEnumerator返回類(lèi)型組合成一個(gè)枚舉器 9 //C#會(huì)自動(dòng)生成一個(gè)IEnumerator類(lèi),該類(lèi)實(shí)現(xiàn)了MoveNext(),Reset(),Current 10 //在C#2.0之前,我們必須自己來(lái)寫(xiě)一個(gè)IEnumerator類(lèi),才實(shí)現(xiàn)上面的接口與屬性 11 class MyCalc : IEnumerable{ 12 int rest = 1; 13 public int x = 1; 14 public int y = 1; 15 16 public IEnumerator GetEnumerator () 17 { 18 for(int i=0; i<y; ++i) 19 { 20 yield return rest = x * rest; 21 } 22 } 23 } 24 25 //示例,如何將一個(gè)函數(shù)寫(xiě)成可以被枚舉的對(duì)象(擁有MoveNext(),Reset(),Current) 26 //C#會(huì)自動(dòng)生成一個(gè)IEnumerator類(lèi),該類(lèi)實(shí)現(xiàn)了MoveNext(),Reset(),Current 27 //在C#2.0之前,我們必須自己來(lái)寫(xiě)一個(gè)IEnumerator類(lèi),才實(shí)現(xiàn)上面的接口與屬性 28 IEnumerable calc(int x, int y){ 29 int rest = 1; 30 for(int i=0; i<y; ++i) 31 { 32 yield return rest = x * rest; 33 } 34 } 35 36 IEnumerator waitprint(){//協(xié)程返回類(lèi)型必須為IEnumerator,它不認(rèn)IEnumerable,如yield return DoCheck (),若DoCheck為IEnumerable,則DoCheck不會(huì)被執(zhí)行 37 38 //StartCoroutine("DoCheck");//啟動(dòng)一個(gè)新的協(xié)程 39 //yield return DoCheck (); //在這里進(jìn)入死循環(huán),若改為StartCoroutine("DoCheck");則不會(huì)進(jìn)入死循環(huán),只會(huì)另外啟動(dòng)一個(gè)協(xié)程 40 41 yield return new WaitForSeconds (5); //暫停5秒,若流程走到了這里,協(xié)程將在這里阻塞5秒才執(zhí)行下面的代碼 42 yield return new GameObject (); 43 yield return 2; 44 } 45 IEnumerable waitPrint(){ 46 yield return 1; 47 yield return 2; 48 } 49 50 IEnumerator DoCheck(){ 51 for(;;){ 52 Debug.Log ("doecheck"); 53 //協(xié)程調(diào)用頻率最高是每幀一次,這里我們指定的等待時(shí)間小于一幀,并不能達(dá)到一幀調(diào)用多次docheck的效果 54 yield return new WaitForSeconds (0.0001f); //0.1毫秒,1/0.0001F = 10000 fps,顯然U3D不可能達(dá)到這個(gè)幀率 55 } 56 } 57 58 void Start () { 59 60 /************************************************************************/ 61 /* 自定義對(duì)象的枚舉測(cè)試,自定義方法的枚舉測(cè)試,這是理解協(xié)程的基礎(chǔ) */ 62 /************************************************************************/ 63 StringBuilder sbd = new StringBuilder(50); 64 foreach(var n in calc (2, 8)){ 65 sbd.Append (n); 66 sbd.Append (","); 67 } 68 69 sbd.Length = 0; 70 MyCalc omc = new MyCalc (){ x = 2, y = 8 }; 71 foreach(var n in omc){ 72 sbd.Append (n); 73 sbd.Append ((",")); 74 } 75 76 77 /************************************************************************/ 78 /* 協(xié)程綜合測(cè)試 */ 79 /************************************************************************/ 80 //U3D協(xié)程特征:本質(zhì)是一個(gè)返回值為IEnumerator的函數(shù),函數(shù)中至少有一條yield return語(yǔ)句。 81 //協(xié)程必須由StartCoroutine來(lái)啟動(dòng) 82 //協(xié)程并非線程,線程是操作系統(tǒng)層的東西,協(xié)程是引擎層面由邏輯調(diào)用來(lái)實(shí)現(xiàn)的,是由一個(gè)線程操作出來(lái)的,在LUA中是由LUA狀態(tài)機(jī)實(shí)現(xiàn),在U3D是由U3D引擎狀態(tài)機(jī)實(shí)現(xiàn)。 83 //在U3D中,協(xié)程是U3D引擎在每幀的update之后調(diào)用一次協(xié)程函數(shù)來(lái)實(shí)現(xiàn),在update()中寫(xiě)一個(gè)死循環(huán),會(huì)發(fā)現(xiàn)程序卡死,協(xié)程也不會(huì)執(zhí)行了。這證明了協(xié)程和主線程是同一線程。 84 //UNITY手冊(cè)的Execution Order of Event Functions一節(jié)詳細(xì)講解了協(xié)程的調(diào)用時(shí)機(jī),從中可以看出協(xié)程只是主線程中的邏輯調(diào)用,并非一個(gè)新線程。 85 86 //StartCoroutine ("DoCheck"); 87 //yield return waitprint (); //waitprint被完整執(zhí)行 88 //yield return waitPrint (); //waitPrint沒(méi)有被執(zhí)行,U3D不認(rèn)這種形式 89 90 91 //協(xié)程返回類(lèi)型必須為IEnumerable。 92 //但不管一個(gè)函數(shù)的返回類(lèi)型是IEnumerable還是IEnumerator,只要函數(shù)體中有一句yield return,編譯器就會(huì)自動(dòng)為該函數(shù)生成一個(gè)IEnumerator類(lèi)型的對(duì)象。 93 //就可以使用此迭代器對(duì)象的MoveNext(), Current等方法,屬性。若是返回類(lèi)型為IEnumerable,編譯器還會(huì)生成GetEnumerator()方法。 94 waitprint ();//直接調(diào)用協(xié)程函數(shù)無(wú)效,不會(huì)進(jìn)入該函數(shù)執(zhí)行,這時(shí)僅相當(dāng)于返回了一個(gè)IEnumerator迭代子的臨時(shí)對(duì)象,并沒(méi)有執(zhí)行具體代碼。 95 96 //只有如下調(diào)用,才會(huì)完整的執(zhí)行協(xié)程函數(shù) 97 IEnumerator i = waitprint (); 98 i.MoveNext (); //從函數(shù)入口執(zhí)行到y(tǒng)ield return new WaitForSeconds (5); 99 i.MoveNext (); //從上一個(gè)yield語(yǔ)句末執(zhí)行到y(tǒng)ield return new GameObject (); 100 i.MoveNext (); //從上一個(gè)yield語(yǔ)句末yield return 2; 101 //下面這種寫(xiě)法并不能達(dá)到上面的效果,原因是每次waitprint ()返回的是一個(gè)不同的臨時(shí)對(duì)象,通過(guò)gethashcode可以發(fā)現(xiàn)。 102 //waitprint ().MoveNext (); 103 //waitprint ().MoveNext (); 104 //waitprint ().MoveNext (); 105 106 //返回值為IEnumerable類(lèi)型的示例 107 //只有返回值為IEnumerable的方法才能用于foreach,因?yàn)樗髮?shí)現(xiàn)GetEnumerator 108 i = waitPrint ().GetEnumerator (); 109 i.MoveNext (); 110 i.MoveNext (); 111 i.MoveNext (); 112 113 print ("done"); 114 } 115 116 void Update(){ 117 transform.Rotate (0, 2, 0); 118 } 119 }?
posted on 2016-10-21 20:09 時(shí)空觀察者9號(hào) 閱讀(...) 評(píng)論(...) 編輯 收藏
總結(jié)
以上是生活随笔為你收集整理的Unity 协程Coroutine综合测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: U3D协程Coroutine之WWW与U
- 下一篇: U3D assetbundle加载