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)
		{
            // test
			editorCoroutineList = new List<EditorCoroutine>();
		}
		if (buffer == null)
		{
			buffer = new List<IEnumerator>();
		}
		if (editorCoroutineList.Count == 0)
		{
			EditorApplication.update += Update;
		}

		// add iterator to buffer first
		buffer.Add(iterator);

		return iterator;
	}

	private static bool Find(IEnumerator iterator)
	{
		// If this iterator is already added
		// Then ignore it this time
		foreach (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 first
		editorCoroutineList.RemoveAll
		(
			coroutine => { return coroutine.MoveNext() == false; }
		);

		// If we have iterators in buffer
		if (buffer.Count > 0)
		{
			foreach (IEnumerator iterator in buffer)
			{
				// If this iterators not exists
				if (!Find(iterator))
				{
					// Added this as new EditorCoroutine
					editorCoroutineList.Add(new EditorCoroutine(iterator));
				}
			}

			// Clear buffer
			buffer.Clear();
		}

		// If we have no running EditorCoroutine
		// Stop calling update anymore
		if (editorCoroutineList.Count == 0)
		{
			EditorApplication.update -= Update;
		}
	}
}

这里需要注意几个地方:

1、EditorApplication.update,这个是一个delegate,可以绑定一个函数,从而在编辑器下执行Update。

2、EditorCoroutineRunner.StartEditorCoroutine(Routine1());  这样可以在编辑器下开启一个协程。

3、另外一个思路是不使用协程,绑定一个Update函数,然后判断www.isDone来获取AssetBundle。这个我并没有实际验证。

时间: 2024-10-11 11:44:27

Unity如何在Editor下执行协程(coroutine)的相关文章

Unity协程(Coroutine)管理类——TaskManager工具分享

Unity协程(Coroutine)管理类--TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 在分享vp_Timer 中提到,没有继承的MonoBehaviour,没有Update,InVoke 和StartCoroutine的机制,vp_Timer就是提供了InVoke的机制,而且还可以统一管理.本篇D.S.Qiu要分享的TaskManager就是一个协程 管理类. TaskManager -- Unit

(zt)Lua的多任务机制——协程(coroutine)

原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定何时执行哪个任务.另外一种就是协作式多任务(cooperative multitasking),它把决定权交给任务,让它们在自己认为合适的时候自愿放弃执行.这两种多任务方式各有优缺点,前者固

并发编程协程(Coroutine)之Gevent

Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译为协同的例程,一般我们都简称为协程. 在linux系统中,线程就是轻量级的进程,而我们通常也把协程称为轻量级的线程即微线程. 进程和协程 下面对比一下进程和协程的相同点和不同点: 相同点:我们都可以把他们看做是一种执行流,执行流可以挂起,并且后面可以在你挂起的地方恢复执行,这实际上都可以看做是con

Unity 动画(UITweener)、协程(Coroutine)和委托(Delegate)队列管理

问题         前段时间,项目中要做奖励界面UI缓动动画要一个接着一个播放,如:先播放达成星星动画,在播放经验数字增加动画,最后播放奖励物品动画. 当然最笨最直接的方法可以类似成语接龙那样,把下个动画的开始播放都写在上一个动画播放完毕委托中.一般直接的方法是实现起来非常之简单,但这里却不是,会看见代码中有一系列播放完毕回调函数(除了最后一个),显然维护起来是否费劲. 把上面的方法进行简化,把回调函数变为一个:维护一个动画的 List 和当前播放动画的索引 index ,然后再回调函数中只需

【Unity笔记】协程Coroutine的简单优化

一个最简单的协程,也至少需要2帧才能完成.第一帧走到yield return null停止,第二帧从此处接着执行完下面的操作.需求:如果缓存中存在某数据则直接使用,否则联网异步下载. private bool cached; // 该数据是否已有缓存 void Start(){ StartCoroutine(Download()); } IEnumerator WorkWhenDownload() { if(cached){ // 直接使用缓存 }else{ // 没有缓存,联网下载 WWW w

Unity下载文件一(www协程下载)

下载功能,是大多数游戏或者软件都需具备的一个基础模块,但是很多人却没有机会去写这个完整功能. 那么我就分享下我写该功能时的随笔整理 本文只说www协程下载,http的同步和异步下载放到下篇 这个简单: WWW wwwServer = new WWW("http://192.168.1.1:8080/Files/ab.assetBundle"); yield return wwwServer; if (string.IsNullOrEmpty(wwwServer.error)) { As

Unity协程(Coroutine)管理类——TaskManager工具分享(转)

尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 在分享vp_Timer 中提到,没有继承的MonoBehaviour,没有Update,InVoke 和StartCoroutine的机制,vp_Timer就是提供了InVoke的机制,而且还可以统一管理.本篇D.S.Qiu要分享的TaskManager就是一个协程 管理类. TaskManager —— Unity3D Managed Coroutines with Start, Stop, Resume ,看

Unity3D 协程 Coroutine

协程(Coroutine)的概念存在于很多编程语言,例如Lua.ruby等.而由于Unity3D是单线程的,因此它同样实现了协程机制来实现一些类似于多线程的功能,但是要明确一点协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用. 协程类型IEnumerator 在内部方法使用 yield return 语句,直观的说语句说在位置便是协程暂停,并且将控制权移交给Unity引擎以及之后继续执行余下逻辑的地方. 例如 IEnumerator Method(){ int i=0;

tornado协程(coroutine)原理

tornado中的协程是如何工作的 本文将按以下结构进行组织,说明tornado中协程的执行原理 协程定义 生成器和yield语义 Future对象 ioloop对象 函数装饰器coroutine 总结 协程定义 Coroutines are computer program components that generalize subroutines for nonpreemptive multitasking, by allowing multiple entry points for su