估計熟悉Unity的人看過或者用過StartCoroutine()ide
假設咱們在場景中有一個UGUI組件, Image:this
將如下代碼綁定到Imageurl
1 using UnityEngine; 2 using System.Collections; 3 using System.Threading; 4 using UnityEngine.UI; 5 6 public class CoroutineDemo : MonoBehaviour { 7 8 // Use this for initialization 9 void Start () { 10 11 Debug.Log (Thread.CurrentThread.Name + ": Start begin. fCount=" + + Time.renderedFrameCount); 12 13 14 this.StartCoroutine (exeuteCoroutine()); 15 } 16 17 // Update is called once per frame 18 void Update () { 19 20 Debug.Log (Thread.CurrentThread.Name + ": Update(): fCount=" + Time.renderedFrameCount); 21 } 22 23 24 public IEnumerator exeuteCoroutine(){ 25 Debug.Log (Thread.CurrentThread.Name + ": Before yield return A, fCount=" + Time.renderedFrameCount); 26 //yield return new WaitForSeconds(1); 27 yield return "A"; 28 // yield return "C"; 29 // yield return "D"; 30 Debug.LogError (Thread.CurrentThread.Name + ": After yield return A, fCount=" + Time.renderedFrameCount); 31 } 32 33 IEnumerator LoadImage() 34 { 35 WWW www=new WWW("http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg"); 36 Image img = this.gameObject.GetComponent<Image> (); 37 38 Debug.Log("Before yield return: " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount); 39 40 yield return www; 41 42 Debug.Log("After yield return, " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount); 43 Rect spriteRect = new Rect (0, 0, www.texture.width, www.texture.height); 44 Sprite imageSprite = Sprite.Create (www.texture, spriteRect, new Vector2 (0.5f, 0.5f)); 45 img.sprite = imageSprite; 46 47 } 48 }
運行以後日誌輸出(Error 日誌是爲了明顯,才這麼打的):spa
fCount 表明的是當前已經渲染的幀數,發現, yield return 以後的代碼, 是在yield return 以後的一幀執行的。線程
若是yield return 以後換成 new WaitForSeconds(1); yield以後的代碼就在1秒後執行。3d
看一下MonoBehaviour的生命週期:日誌
發現, 在StartCortinue()傳入的方法中, 能夠yield return 的類型有:code
yield return null;協程
yield return WaitForSeconds(); (實際上, 繼承自 YieldInstruction的均可以)blog
yield return WWW;
若是將例子中的代碼改爲加載圖片:
1 void Start () { 3 Debug.Log (Thread.CurrentThread.ManagedThreadId + ": Start begin. fCount=" + + Time.renderedFrameCount); 6 this.StartCoroutine (LoadImage()); 7 }
1 IEnumerator LoadImage() 2 { 3 WWW www=new WWW("http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg"); 4 Image img = this.gameObject.GetComponent<Image> (); 5 6 Debug.Log("Before yield return: " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount); 7 8 yield return www; 9 10 Debug.Log("After yield return, " + www.url + " is done? " + www.isDone + ", rf=" + Time.renderedFrameCount); 11 Rect spriteRect = new Rect (0, 0, www.texture.width, www.texture.height); 12 Sprite imageSprite = Sprite.Create (www.texture, spriteRect, new Vector2 (0.5f, 0.5f)); 13 img.sprite = imageSprite; 14 15 }
經過輸出日誌, 你會發現, yield return www;以後的代碼, 是在www.isDone以後, 也就是圖片加載完畢以後才執行的!
Before yield return: http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg is done? False, rf=1 UnityEngine.Debug:Log(Object) <LoadImage>c__Iterator6:MoveNext() (at Assets/Scripts/CoroutineDemo.cs:38) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) CoroutineDemo:Start() (at Assets/Scripts/CoroutineDemo.cs:14) After yield return, http://pic89.nipic.com/file/20160211/22571617_214730734684_2.jpg is done? True, rf=34 UnityEngine.Debug:Log(Object) <LoadImage>c__Iterator6:MoveNext() (at Assets/Scripts/CoroutineDemo.cs:42)
總結:
yield return 搭配上WaitForSecond, WWW, 能夠達到延時執行的效果。
可是, 特別注意的是, StartCoroutine()並無開啓新的線程來執行, 仍是執行在與Start(), Update()相同的主線程中!