Unity3D 编辑器扩展 Editor中使用协程

在运行时环境下,我们可以利用协程 Coroutines ,通过UnityWebRequest 或者WWW 来做文件下载,贴图加载等操作。
但是在编辑器模式下,StartCoroutine() 并不能起作用。

比如不能通过WWW 来下载文件。(可以通过WebClient 等.net自身类库来实现) 然而一些对贴图等Unity原生资源的操作,又不允许在其他线程中操作。
那么我们如何来实现类似运行时协程这样的异步操作呢?

AssetStore中的一个插件实现了我们需要的这个功能 ,我们可以通过该插件,在做编辑器工具开发的过程中实现协程操作。

下载地址:https://github.com/marijnz/unity-editor-coroutines/tree/master/Assets

示例如下:

using UnityEngine;
using System.Collections;
using UnityEditor;

namespace marijnz.EditorCoroutines
{
	public class CoroutineWindowExample : EditorWindow
	{
		[MenuItem("Window/Coroutine Example")]
		public static void ShowWindow()
		{
			EditorWindow.GetWindow(typeof(CoroutineWindowExample));
		}

		void OnGUI()
		{
			if (GUILayout.Button("Start"))
			{
				this.StartCoroutine(Example());
			}

			if (GUILayout.Button("Start WWW"))
			{
				this.StartCoroutine(ExampleWWW());
			}

			if (GUILayout.Button("Start Nested"))
			{
				this.StartCoroutine(ExampleNested());
			}

			if (GUILayout.Button("Stop"))
			{
				this.StopCoroutine("Example");
			}
			if (GUILayout.Button("Stop all"))
			{
				this.StopAllCoroutines();
			}

			if (GUILayout.Button("Also"))
			{
				this.StopAllCoroutines();
			}

			if (GUILayout.Button("WaitUntil/WaitWhile"))
			{
				status = false;
				this.StartCoroutine(ExampleWaitUntilWhile());
			}

			if (GUILayout.Button("Switch For WaitUntil/WaitWhile:" + (status ? "On" : "Off")))
			{
				status = !status;
				EditorUtility.SetDirty(this);
			}
		}

		private bool status;

		IEnumerator ExampleWaitUntilWhile()
		{
			yield return new WaitUntil(()=>status);
			Debug.Log("Switch On");
			yield return new WaitWhile(()=>status);
			Debug.Log("Switch Off");
		}

		IEnumerator Example()
		{
			while (true)
			{
				Debug.Log("Hello EditorCoroutine!");
				yield return new WaitForSeconds(2f);
			}
		}

		IEnumerator ExampleWWW()
		{
			while (true)
			{
				var www = new WWW("https://unity3d.com/");
				yield return www;
				Debug.Log("Hello EditorCoroutine!" + www.text);
				yield return new WaitForSeconds(2f);
			}
		}

		IEnumerator ExampleNested()
		{
			while (true)
			{
				yield return new WaitForSeconds(2f);
				Debug.Log("I'm not nested");
				yield return this.StartCoroutine(ExampleNestedOneLayer());
			}
		}

		IEnumerator ExampleNestedOneLayer()
		{
			yield return new WaitForSeconds(2f);
			Debug.Log("I'm one layer nested");
			yield return this.StartCoroutine(ExampleNestedTwoLayers());
		}

		IEnumerator ExampleNestedTwoLayers()
		{
			yield return new WaitForSeconds(2f);
			Debug.Log("I'm two layers nested");
		}


		class NonEditorClass
		{
			public void DoSomething(bool start, bool stop, bool stopAll)
			{
				if (start)
				{
					EditorCoroutines.StartCoroutine(Example(), this);
				}
				if (stop)
				{
					EditorCoroutines.StopCoroutine("Example", this);
				}
				if (stopAll)
				{
					EditorCoroutines.StopAllCoroutines(this);
				}
			}

			IEnumerator Example()
			{
				while (true)
				{
					Debug.Log("Hello EditorCoroutine!");
					yield return new WaitForSeconds(2f);
				}
			}
		}
	}
}

插件中的EditorCoroutineExtensions.cs 对EditorWindow 做了一些扩展。所以可以直接在EditorWindow的子类中 调用 类似 this.StartCoroutine(Example());等函数。 跟运行时调用官方的协程 API 一样的格式。

Unity技术交流 微信公众号 UnityAsk,QQ群:891920228

你可能感兴趣的:(Unity3D编辑器)