[Unity编辑器扩展基础总结] 第1章 编辑器扩展中的特殊文件夹
Unity编辑器拓展基础总结
前言
使用Unity编辑器扩展开发过很多跟项目配套的工具,写这些文章的目的是为了总结一下其中的知识点,方便自己日后查阅。其中也参考了很多资料:
Unity编辑器拓展手册 原文地址:http://49.233.81.186/guicreation.html
下图是一个任务编辑器
第1章 编辑器扩展中的特殊文件夹
1.1 编辑器文件夹 - Editor
Editor下面放的所有资源文件或者脚本文件都不会被打进发布包中,并且脚本也只能在编辑器模式下使用。一般我们会把一些工具类的脚本放在这里,或者是一些编辑时用的DLL。
比如我们现在要做类似任务编辑器、地图编辑器这种的工具时,那么编辑器的代码放在这里是再好不过了,因为实际运行时我们只需要编辑器生成的文件,而不需要编辑器的核心代码。
1、Editor文件夹是一个用于使用Editor API的特殊文件夹。通常,编辑器开发的API无法在运行时上运行,会直接报错。这是因为在生成Assembly-CSharp.dll的过程中,它是UnityEditor.dll,运行时并未对其进行引用。
但是,在开发过程中由Unity编辑器生成的assembly-CSharp.dll不会导致脚本编译错误,这是因为它会引用UnityEditor.dll。
2、UnityEditor可以生成为Assembly-CSharp-Editor.dll,这样就可以分离编辑器API和运行时API。
通过编译“Editor”文件夹中的脚本文件来生成Assembly-CSharp-Editor.dll。在发布时不包含Assembly-CSharp-Editor.dll,因此不会发生任何发布错误。
3、Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以。比如目录:/xxx/xxx/Editor 和 /Editor 是一样的,无论多少个叫Editor的文件夹都可以。
但是,如果在Standard Assets,Pro Standard Assets和Plugins文件夹内创建的Editor文件夹,里面的脚本将被编译为到Assembly-CSharp-Editor-firstpass.dll。
要注意的是,我们可以从Assembly-CSharp-Editor引用firstpass,但是相反,不能从firstpass引用Assembly-CSharp-Editor.dll。
在运行时脚本中添加编辑器API脚本
在运行时脚本中加入一些编辑器API是很常见的需求。在这种情况下,我们使用预处理指令#define。UNITY_EDITOR意思是只在Unity编辑器状态下执行。在打包发布的时候将删除#if UNITY_EDITOR中包含的代码,因为在发布时没有在脚本编译中定义UNITY_EDITOR。
using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif public class NewBehaviourScript : MonoBehaviour { void OnEnable () { #if UNITY_EDITOR EditorWindow.GetWindow<ExampleWindow> (); #endif } }
1.2 编辑器默认资源文件夹 - Editor Default Resources(必须有空格)
这是一个用于存储仅用于编辑器扩展资源的文件夹,你可以把编辑器用到的一些资源放在这里,比如图片、文本文件、等等。
它和Editor文件夹一样都不会被打到最终发布包里,仅仅用于开发时使用。你可以直接通过EditorGUIUtility.Load去读取该文件夹下的资源。
注意:中间是有空格的,它必须放在Project视图的根目录下,如果你想放在/xxx/xxx/Editor Default Resources 这样是不行的。你可以把编辑器用到的一些资源放在这里,比如图片、文本文件、等等。
var tex = EditorGUIUtility.Load ("logo.png") as Texture;
处理内置资源
最初,“Editor Default Resources”文件夹是用于处理内置资源的文件夹,并不旨在供用户将资源放入此文件夹。
此文件夹的目的是“替换内置资源”。
加载内置资源
编辑器使用的内置资源被组合到一个资源包中。为了进行确认,我们可以获取EditorGUIUtility.GetEditorAssetBundle
资源包,使用AssetBundle.GetAllAssetNames检查路径。
[InitializeOnLoadMethod]
static void GetBultinAssetNames ()
{
var flags = BindingFlags.Static | BindingFlags.NonPublic;
var info = typeof(EditorGUIUtility).GetMethod ("GetEditorAssetBundle", flags);
var bundle = info.Invoke (null, new object[0]) as AssetBundle;
foreach (var n in bundle.GetAllAssetNames()) {
Debug.Log (n);
}
}
确认路径后,使用EditorGUIUtility.Load
加载资源。确保使用“Load”加载资源,不要使用刚才AssetBundle加载的资源。
EditorGUIUtility.Load
首先在Unity项目的“Assets/Editor Default Resources/ + 路径”中查找资源。如果里面有资源,就使用该资源,否则从内置的AssetBundle中加载该资源。该规范允许我们“替换内置资源”。