在处理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。

这个我并没有实际验证。

4、www能够正常的载入出AssetBundle。可是isDone的变量一直为false。额外要注意由于Editor模式下不存在退出游戏清理资源的概念,所以要注意处理已载入的assetbundle的情况,否则可能会报冲突的错误。

5、理论上仅仅支持yield return null这种情况,延时要自己处理。

Unity协程的原理是引擎在特定条件下运行MoveNext运行以下的语句。在上面的代码中无论是延时还是其它的东西,都是每帧运行MoveNext,这样WaitForSeconds这种协程是无效的。

www的情况比較特殊,尽管理论上也是会有问题的。可是确实能够正常的取到结果。

Unity怎样在Editor下运行协程(coroutine)的更多相关文章

  1. Unity协程Coroutine使用总结和一些坑

    原文摘自 Unity协程Coroutine使用总结和一些坑 MonoBehavior关于协程提供了下面几个接口: 可以使用函数或者函数名字符串来启动一个协程,同时可以用函数,函数名字符串,和Corou ...

  2. 【Unity】协程Coroutine及Yield常见用法

    最近学习协程Coroutine,参考了别人的文章和视频教程,感觉协程用法还是相当灵活巧妙的,在此简单总结,方便自己以后回顾.Yield关键字的语意可以理解为“暂停”. 首先是yield return的 ...

  3. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

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

    博客分类: Unity3D插件学习,工具分享 源码分析   Unity协程(Coroutine)管理类——TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处 ...

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

    原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...

  6. 协程coroutine

    协程(coroutine)顾名思义就是“协作的例程”(co-operative routines).跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程 ...

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

    并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定 ...

  8. Python并发编程协程(Coroutine)之Gevent

    Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译 ...

  9. Python之协程(coroutine)

    Python之协程(coroutine) 标签(空格分隔): Python进阶 coroutine和generator的区别 generator是数据的产生者.即它pull data 通过 itera ...

随机推荐

  1. Java中的Switch用法

    一.java当中的switch与C#相比有以下区别 注:在java中switch后的表达式的类型只能为以下几种:byte.short.char.int(在Java1.6中是这样),   在java1. ...

  2. Char Tools,方便的字符编码转换小工具

    工作关系,常有字符编码转换方面的需要,写了这个小工具 Char Tools是一款方便的字符编码转换小工具,基于.Net Framework 2.0 Winform开发 主要功能 URL编码:URLEn ...

  3. 网页、JavaScript 的DOM操作

    HTML DOM (文档对象模型) 当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model). HTML DOM 模型被构造为对象的树.  Windows 对象操作 ...

  4. (转)弹出窗口lhgDialog API文档

    应用到你的项目 如果您使用独立版本的lhgDialog窗口组件,您只需在页面head中引入lhgcore.lhgdialog.min.js文件,4.1.1+版本做了修改可以和jQuerya库同时引用, ...

  5. java开发软件的安装

    jdk+eclipse+svn+maven+mysql+tomcat7.0+sublime安装包和jar插件 配置管理工具-SVN http://download.csdn.net/detail/u0 ...

  6. Java system.getproperty获取环境属性

    序号 属性 说明 1 java.version Java 运行时环境版本 2 java.vendor Java 运行时环境供应商 3 java.vendor.url Java 供应商的 URL 4 j ...

  7. JS中,如何查询一个对象的所有属性

    var res = ""; for(var p in object) { res += p + ","; } alert(res);

  8. AJAX 跨域

    1.说到ajax就会遇到的两个问题 1.1AJAX以何种格式来交换数据                    1.自定义字符串 2.XML描述 3.JSON描述(建议使用)          1.2如 ...

  9. [GIT] warning: LF will be replaced by CRLF问题解决方法

    原文链接[http://michael-roshen.iteye.com/blog/1328142] 开发环境: 操作系统: windows xp ruby 1.9.2 rails 3.1.3 git ...

  10. quartz spring 时间配置

    关于时间配置, 1前面带0和不带0的区别是???   (开始时间,带0以整点整分整秒开始,不带的以启动时间定时循环??) 比如 0 7/37 * * * ?  表示每个小时的第7分钟开始执行,然后隔三 ...