本文主要是介绍Unity如何在Editor下执行协程(coroutine),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在处理Unity5新的AssetBundle的时候,我有一个需求,需要在Editor下(比如一个menuitem的处理函数中,游戏没有运行,也没有MonoBehaviour)加载AssetBundle。而加载AssetBundle的时候又需要使用yield return www;这样的协程用法。
所以就有了一个需求,在Editor下执行协程。我从网上找到一个EditorCoroutine,其代码如下:
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;public static class EditorCoroutineRunner
{private class EditorCoroutine : IEnumerator{private Stack<IEnumerator> executionStack;public EditorCoroutine(IEnumerator iterator){this.executionStack = new Stack<IEnumerator>();this.executionStack.Push(iterator);}public bool MoveNext(){IEnumerator i = this.executionStack.Peek();if (i.MoveNext()){object result = i.Current;if (result != null && result is IEnumerator){this.executionStack.Push((IEnumerator)result);}return true;}else{if (this.executionStack.Count > 1){this.executionStack.Pop();return true;}}return false;}public void Reset(){throw new System.NotSupportedException("This Operation Is Not Supported.");}public object Current{get { return this.executionStack.Peek().Current; }}public bool Find(IEnumerator iterator){return this.executionStack.Contains(iterator);}}private static List<EditorCoroutine> editorCoroutineList;private static List<IEnumerator> buffer;public static IEnumerator StartEditorCoroutine(IEnumerator iterator){if (editorCoroutineList == null){// testeditorCoroutineList = new List<EditorCoroutine>();}if (buffer == null){buffer = new List<IEnumerator>();}if (editorCoroutineList.Count == 0){EditorApplication.update += Update;}// add iterator to buffer firstbuffer.Add(iterator);return iterator;}private static bool Find(IEnumerator iterator){// If this iterator is already added// Then ignore it this timeforeach (EditorCoroutine editorCoroutine in editorCoroutineList){if (editorCoroutine.Find(iterator)){return true;}}return false;}private static void Update(){// EditorCoroutine execution may append new iterators to buffer// Therefore we should run EditorCoroutine firsteditorCoroutineList.RemoveAll(coroutine => { return coroutine.MoveNext() == false; });// If we have iterators in bufferif (buffer.Count > 0){foreach (IEnumerator iterator in buffer){// If this iterators not existsif (!Find(iterator)){// Added this as new EditorCoroutineeditorCoroutineList.Add(new EditorCoroutine(iterator));}}// Clear bufferbuffer.Clear();}// If we have no running EditorCoroutine// Stop calling update anymoreif (editorCoroutineList.Count == 0){EditorApplication.update -= Update;}}
}
这里需要注意几个地方:
1、EditorApplication.update,这个是一个delegate,可以绑定一个函数,从而在编辑器下执行Update。
2、EditorCoroutineRunner.StartEditorCoroutine(Routine1()); 这样可以在编辑器下开启一个协程。
3、另外一个思路是不使用协程,绑定一个Update函数,然后判断www.isDone来获取AssetBundle。这个我并没有实际验证。
文章转载自Unity如何在Editor下执行协程(coroutine),感谢原作者提供好文章
这篇关于Unity如何在Editor下执行协程(coroutine)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!