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。
这个我并没有实际验证。
4、www能够正常的载入出AssetBundle。可是isDone的变量一直为false。额外要注意由于Editor模式下不存在退出游戏清理资源的概念,所以要注意处理已载入的assetbundle的情况,否则可能会报冲突的错误。
5、理论上仅仅支持yield return null这种情况,延时要自己处理。
Unity协程的原理是引擎在特定条件下运行MoveNext运行以下的语句。在上面的代码中无论是延时还是其它的东西,都是每帧运行MoveNext,这样WaitForSeconds这种协程是无效的。
www的情况比較特殊,尽管理论上也是会有问题的。可是确实能够正常的取到结果。
Unity怎样在Editor下运行协程(coroutine)的更多相关文章
- Unity协程Coroutine使用总结和一些坑
原文摘自 Unity协程Coroutine使用总结和一些坑 MonoBehavior关于协程提供了下面几个接口: 可以使用函数或者函数名字符串来启动一个协程,同时可以用函数,函数名字符串,和Corou ...
- 【Unity】协程Coroutine及Yield常见用法
最近学习协程Coroutine,参考了别人的文章和视频教程,感觉协程用法还是相当灵活巧妙的,在此简单总结,方便自己以后回顾.Yield关键字的语意可以理解为“暂停”. 首先是yield return的 ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
- Unity协程(Coroutine)管理类——TaskManager工具分享
博客分类: Unity3D插件学习,工具分享 源码分析 Unity协程(Coroutine)管理类——TaskManager工具分享 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处 ...
- (zt)Lua的多任务机制——协程(coroutine)
原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...
- 协程coroutine
协程(coroutine)顾名思义就是“协作的例程”(co-operative routines).跟具有操作系统概念的线程不一样,协程是在用户空间利用程序语言的语法语义就能实现逻辑上类似多任务的编程 ...
- Lua的多任务机制——协程(coroutine)
并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上有这么两种多任务技术,一种是抢占式多任务(preemptive multitasking),它让操作系统来决定 ...
- Python并发编程协程(Coroutine)之Gevent
Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate routine的缩写,直接翻译 ...
- Python之协程(coroutine)
Python之协程(coroutine) 标签(空格分隔): Python进阶 coroutine和generator的区别 generator是数据的产生者.即它pull data 通过 itera ...
随机推荐
- 应用按home键无最近应用
在应用的AndroidManifest里面添加加载模式
- HDU 4119Isabella's Message2011成都现场赛I题(字符串模拟)
Isabella's Message Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- Adobe/Flash Media Server 5.0 linux 64位系统下的安装
一.下载 Adobe/Flash MS5.0下载地址: http://fs1.d-h.st/download/00036/VOt/adobemediaserver_5_ls1_linux64.tar. ...
- ViewPager欢迎页
布局 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to ...
- java事件演示
package cn.stat.p3.windowdemo; import java.awt.Button; import java.awt.FlowLayout; import java.awt.F ...
- POJ3104 Drying(二分查找)
POJ3104 Drying 这个题由于题目数据比较大(1 ≤ ai ≤ 109),采用贪心的话肯定会超时,自然就会想到用二分. 设C(x)为true时表示所用时间为X时,可以把所有的衣服都烘干或者自 ...
- 使vim中Syntastic支持C++11
安装好Syntastic后发现不支持c++11,会提示错误incompatible with c++98,解决方法如下: .vimrc中加入: let g:syntastic_cpp_compiler ...
- SDWebImage 官方文档
API documentation is available at CocoaDocs - SDWebImage Using UIImageView+WebCache category with UI ...
- 从现在开始使用nodejs开发的几点答疑
1.为什么要开始用nodejs, 而不是php 理由有三点: 因为我是前端程序员出身,nodejs都是用javascript写的,这样相当于前端和后端都使用javascript,开发更加有效率.当然很 ...
- 基本套接字总结(@function)
最近学习了下UNIX下的网络编程.为了以后查询方便,总结在这里. 首先套接字的地址定义: IPv4地址和IPv6地址定义见<netinet/in.h>头文件定义.为了能够顺利转换不同的套接 ...