第62節 - Unity: StartCoroutine, StopCoroutine, IEnumerator & Yield
這一節我會介紹Unity的以下方法:
1: StartCoroutine(), IEnumerator & Yield
2: Yield WaitforSecond()
3: StopCoroutine()
1.0 甚麼是Unity的StartCoroutine(), IEnumerator & Yield?
正常如果一個方法包含了一個For-Loop Statement,For-Loop Statement會完成所有a=1至 a=5才繼續其他部分,如下圖:

- 調用(Call) methodA()方法。
- For-Loop Statement會完成所有a=1至 a=5才繼續其他部分。
- 執行結果。
但是如果我們改用Unity的StartCoroutine()方法來調用IEumerator Type的methodA()方法,當For-Loop Statement執行到yield return statement時,For-Loop就會被暫停和先跳離methodA()方法去同步執行StartCoroutine()方法之後的程式,再繼續For-Loop部分去完成所有a=1至 a=5,如下圖:
注意1: 有一個很重要的概念關於IEnumerator & Yield的,就是當執行到yield return時,如果此時a=1,For-Loop會被暫停和先跳離methodA()方法去同步執行StartCoroutine()之後的程式,再繼續For-Loop部分去完成所有a=2至 a=5。 則電腦會記錄上次已經執行的數值,
繼續 下一個數值。
注意2: StartCoroutine()方法就是Unity用來調用IEumerator Type的方法。

- Call methodA()方法。
- 當For-Loop Statement執行到yield return statement時,For-Loop就會被暫停和先跳離methodA()方法去同步執行StartCoroutine()方法之後的程式。
- 再繼續For-Loop部分去完成所有a=2至 a=5。
2.0 甚麼要學Unity: StartCoroutine(), StopCoroutine(), IEnumerator & Yield?
最主要原因是我們會在下一節第62節 - Unity: Splash Screen用到StartCoroutine()方法和IEumerator & Yield的特性去做出過場(Splash Screen)效果。
3.0 Case 1: For-Loop Statement

- 建立一個新Project。
- 在Hierarchy區域內建立一個GameObject GameObject1。
- 在Assets區域內建立一個C# Script MyScript1。
- 把C# Script拖放到GameObject1內。

- 用Debug.Log()方法顯示"Start1"。
- 執行methodA()方法內的For-Loop Statement(a=1至a=5)。
- 用Debug.Log()方法顯示"Start2"。

- 顯示"Start1"。
- 顯示For-Loop Statement(a=1至a=5)。
- 顯示"Start2"。
3.0 Case Study
3.1 Case1: StartCoroutine(), IEnumerator & Yield

- 在Hierarchy區域內建立一個GameObject GameObject2。
- 在Assets區域內建立一個C# Script MyScript2。
- 把C# Script拖放到GameObject2內。

- 用Debug.Log()方法顯示"Start1"。
- 執行methodA()方法內的For-Loop Statement(a=1)和yield return。
- 用Debug.Log()方法顯示"Start2"。
- 繼續執行methodA()方法內的For-Loop Statement(a=2至a=5)和yield return。

- 顯示"Start1"。
- 顯示For-Loop Statement(a=1)。
- 顯示"Start2"。
- 繼續顯示For-Loop Statement(a=2至a=5)和yield return。
3.2 Case 2: Yield WaitForSecond()

- 在Hierarchy區域內建立一個GameObject GameObject3。
- 在Assets區域內建立一個C# Script MyScript3。
- 把C# Script拖放到GameObject3內。

- 在yield return加入new WaitForSecond(5),則等待5秒。

- 顯示For-Loop Statementa=1後,等待5秒,再每5秒顯示a=2至a=5。
3.3 Case 3: StopCoroutine()

- 在Hierarchy區域內建立一個GameObject GameObject4。
- 在Assets區域內建立一個C# Script MyScript4。
- 把C# Script拖放到GameObject4內。

- 在update()方法內加入Input.GetKeyDown()方法,當按"Space"鍵,StopCoroutine()方法就會被執行,停止執行StartCoroutine()方法。
- 我們設定a=1至a=59作示範,等大家有足夠時間按"Space"鍵。

- 當按"Space"鍵,StopCoroutine()方法就會被執行,停止執行StartCoroutine()方法。
3.4 Case 4: FadeIn Effect

- 在Hierarchy區域內建立一個GameObject GameObject5。
- 再在Hierarchy區域內建立一個Canvas Image Element。
- 在Assets區域內建立一個C# Script MyScript5。
- 把C# Script拖放到GameObject5內。

- 選擇Canvas。
- 設定Render Mode = Screen Space - Camera。
- 把Main Camera拖放到Render Camera內 。
- 設定UI Scale Mode = Scale With Screen Size。
- 設定Reference Resolution = 2048 x 1536,Screen Match Mode = Expand。

- 選擇Image。
- 設定Rect Transform = 1024 x 768。
- 把圖片拖放到Source Image內 。

- 再選擇Color 。
- 設定A = Alpha = 0 = Transparerent。

- 建立Image物件img,在Inspector區域內就可以把你喜歡的圖片拖放到Image物件img內 。
- 在Start()方法內執行StartCoroutine("FadeIn")。
- 當For-Loop Statement執行到yield return時,i的值會被儲存,For-Loop就會被暫停和先跳離FadeIn()方法去同步執行StartCoroutine()方法之後的程式,再繼續For-Loop部分去完成所有i的值。
3.5 Result (執行結果)
Fade In Effect成功被執行。

3.6 For-Loop without Yield Return
我們試試如果把StartCoroutine("FadeIn")方法改為普通FadeIn()方法,再把yield return null去除,看看執行結果有甚麼分別。

- 在Start()方法內執行FadeIn()方法。
- 加入一個OnRenderObject()方法,它用來顯示圖片在屏幕上之前的i值 。
- FadeIn()方法,把yield return null去除。

- 執行結果。大家可以發現,普通FadeIn()方法只會完成所有For-Loop Statement,才會執行OnRenderObject()方法,則i=0.995999,所以沒有Fade In效果出現。