public static void KillCoroutine(ref EditorCoroutine coroutine) { if (uiCoroutineState.editorCoroutineYieldInstruction == coroutine) { uiCoroutineState = null; coroutine = null; EditorUtility.ClearProgressBar(); return; } if (KillCoroutine(ref coroutine, ref coroutineStates)) { return; } if (KillCoroutine(ref coroutine, ref finishedThisUpdate)) { return; } }
public void Tick() { if (coroutine != null) { // First check if we have been canceled by the UI. If so, we need to stop before doing any wait processing if (canceled) { Stop(); return; } // Did the last Yield want us to wait? bool isWaiting = false; var now = DateTime.Now; if (current != null) { if (currentType == typeof(WaitForSeconds)) { // last yield was a WaitForSeconds. Lets update the timer. var delta = now - lastUpdateTime; timer -= (float)delta.TotalSeconds; if (timer > 0.0f) { isWaiting = true; } } else if (currentType == typeof(WaitForEndOfFrame) || currentType == typeof(WaitForFixedUpdate)) { // These dont make sense in editor, so we will treat them the same as a null return... isWaiting = false; } else if (currentType == typeof(UnityWebRequest)) { // Web download request, lets see if its done! var www = current as UnityWebRequest; if (!www.isDone) { isWaiting = true; } } else if (currentType.IsSubclassOf(typeof(CustomYieldInstruction))) { // last yield was a custom yield type, lets check its keepWaiting property and react to that var yieldInstruction = current as CustomYieldInstruction; if (yieldInstruction.keepWaiting) { isWaiting = true; } } else if (currentType == typeof(EditorCoroutine)) { // Were waiting on another coroutine to finish var editorCoroutine = current as EditorCoroutine; if (!editorCoroutine.HasFinished) { isWaiting = true; } } else if (typeof(IEnumerator).IsAssignableFrom(currentType)) { // if were just seeing an enumerator lets assume that were seeing a nested coroutine that has been passed in without calling start.. were start it properly here if we need to if (nestedCoroutine == null) { nestedCoroutine = EditorCoroutineRunner.StartCoroutine(current as IEnumerator); isWaiting = true; } else { isWaiting = !nestedCoroutine.HasFinished; } } else if (currentType == typeof(Coroutine)) { // UNSUPPORTED UnityEngine.Debug.LogError("Nested Coroutines started by Unity's defaut StartCoroutine method are not supported in editor! please use EditorCoroutineRunner.Start instead. Canceling."); canceled = true; } else { // UNSUPPORTED Debug.LogError("Unsupported yield (" + currentType + ") in editor coroutine!! Canceling."); canceled = true; } } lastUpdateTime = now; // have we been canceled? if (canceled) { Stop(); return; } if (!isWaiting) { // nope were good! tick the coroutine! bool update = coroutine.MoveNext(); if (update) { // yup the coroutine returned true so its been ticked... // lets see what it actually yielded current = coroutine.Current; if (current != null) { // is it a type we have to do extra processing on? currentType = current.GetType(); if (currentType == typeof(WaitForSeconds)) { // its a WaitForSeconds... lets use reflection to pull out how long the actual wait is for so we can process the wait var wait = current as WaitForSeconds; FieldInfo m_Seconds = typeof(WaitForSeconds).GetField("m_Seconds", BindingFlags.NonPublic | BindingFlags.Instance); if (m_Seconds != null) { timer = (float)m_Seconds.GetValue(wait); } } else if (currentType == typeof(EditorStatusUpdate)) { // Special case yield that wants to update the UI! var updateInfo = current as EditorStatusUpdate; if (updateInfo.HasLabelUpdate) { Label = updateInfo.Label; } if (updateInfo.HasPercentUpdate) { PercentComplete = updateInfo.PercentComplete; } } } } else { // Coroutine returned false so its finally finished!! Stop(); } } } }