為了理解 Coroutine 怎樣處理資料, 認真的研究一下 IEnumerator
嘗試在不使用 Unity StartCoroutine() 的情況下, 是怎樣自己控制執行的, 測試了一下.
就只是 Unity 自己定的 YieldInstruction 有點麻煩, 要自己想辦法處理甚麼時候結束..
reflection 可能是一條出路?
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestCoroutine : MonoBehaviour
{
private IEnumerator iter;
private void OnEnable()
{
iter = MyEnumerator();
Debug.ClearDeveloperConsole();
}
private IEnumerator MyEnumerator()
{
var a = 1;
var b = 2;
var c = -1;
Debug.Log($"Step 1, A{a} + b{b} = C{c}");
yield return "First block";
c = a + b;
Debug.Log($"Step 2, A{a} + b{b} = C{c}");
yield return 2;
c = 10000;
Debug.Log($"Step 3, A{a} + b{b} = C{c}");
yield return new WaitForSeconds(3f);
Debug.LogWarning("BOOM ! 3 second.");
}
object lastObj = null;
public void Update()
{
bool skip = lastObj is YieldInstruction;
if (!(skip || Input.GetKeyUp(KeyCode.Space)))
return;
if (iter.MoveNext())
{
lastObj = iter.Current;
if (lastObj == null)
{
}
else if (lastObj is CustomYieldInstruction cy)
{
// cy.keepWaiting;
if (cy is WaitWhile) { }
else if (cy is WaitUntil) { }
else if (cy is WaitForSecondsRealtime) { }
}
else if (lastObj is YieldInstruction u3d)
{
// need to handle unity3d's WaitFor family.
Debug.Log($"U3D waiting {u3d.GetType()}");
if (u3d is WaitForSeconds wfs)
{
Debug.Log(wfs);
}
else if (u3d is WaitForEndOfFrame) { }
else if (u3d is WaitForFixedUpdate) { }
}
else if (lastObj is string str)
{
Debug.Log($"It's str = {str}");
}
else if (lastObj is int i)
{
Debug.Log($"It's int = {i}");
}
else
{
Debug.Log($"What is this ? {lastObj.GetType()}");
}
}
lastObj = null;
}
}