Translated by Xdestiny
2017/10/14
日文原文地址:http://anchan828.github.io/editor-manual/web/part2-beginner.html。
渣翻,有些东西相当不确定,禁止转载
在Editor能扩展的最初阶段,有一些必须要知道的东西。在这一章节,迈入Editor扩展世界第一步前,将说明与Editor扩展相关的重要的文件夹。
Editor文件夹是一个特别的文件夹,专门为了Editor API的使用而存在。一般来说,Editor API是不能够在Runtime的时候生效的。
在Assets文件夹下直接生成下面的这段代码,然后试一下在Build Settings窗口中进行Build。
using UnityEngine;
using UnityEditor;
public class NewBehaviourScript : MonoBehaviour
{
}
这么做的话编译将会失败,类似于下面的错误报告将会被显示出来。
这是因为Build时生成的Assembly-CSharp.dll没有找到UnityEditor.dll的缘故。
所以,在Unity Editor中生成Assemble-CSharp.dll时,由于没有UnityEditor.dll的引用,会引起脚本的编译错误。Build生成Assembly-CSharp.dll的时候,不会添加UnityEditor.dll的引用这件事请记住。如果不知道的话,有可能就找不到“突然Build就无法通过了”的原因。
那么,这样的话还是不能够使用Editor API。Build的时候,去除所有使用到Editor API的脚本也是一种方法。不过,这也太费事了。
UnityEditor中Assembly-CSharp-Editor.dll生成的时候,如果Editor API和Runtime API分开编译的话,这个问题就解决了。Assembly-CSharp-Editor.dll就是这么编译的,因此不会发生编译错误。Editor文件夹下的脚本编译生成Assembly-CSharp-Editor.dll。
Editor文件夹的位置并没有特别的限制,同时生成多个也是可以的。
- Assets/Editor
- Assets/MyFolder/Scripts/Editor
- Assets/Standard Assets/Editor
不过,脚本文件是放在”Standard Assets”, “Pro Standard Assets”, “Plugin”这几个文件夹中的Editor文件夹的场合下,脚本编译会生成Assembly-CSharp-Editor-firstpass.dll。
Assembly-CSharp-Editor能够引用firstpass。但反过来、firstpass是不能够引用 Assembly-CSharp-Editor.dll的。这点务必注意。(译注: 这点可以参考Unity的官方文档,脚本编译顺序以及特殊文件夹)
在Runtime时需要执行的脚本有时候会包含Editor API。 这个场合下需要使用#define
。UnityEditor上已经有UNITY_EDITOR
的宏定义。Build的时候,脚本编译是没有UNITY_EDITOR
的定义的。因此#if UNITY_EDITOR
中包含的代码将会被去除。
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class NewBehaviourScript : MonoBehaviour
{
void OnEnable ()
{
#if UNITY_EDITOR
EditorWindow.GetWindow ();
#endif
}
}
和”Resources”文件夹类似,这个文件夹是存放Editor技能扩展中所使用的资源文件。”Editor Default Resources“文件夹中存放的Asset可以使用EditorGUIUtility.Load
进行访问。
var tex = EditorGUIUtility.Load ("logo.png") as Texture;
从根本上来说,”Editor Default Resources”这个文件夹的目的并不单纯只是”让用户放置资源”。
这个文件夹的目的是”替换Build-in的资源”。
(译注:有点看不懂)
要在Editor中使用build-in的资源,需要所有的资源打包成一个AssetBundle文件。使用EditorGUIUtility.GetEditorAssetbundle
来获得AssetBundle。
[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
读取Asset。注意,只能使用Load
方法读取Asset。不能从之前获得的AssetBundle中进行读取。
EditorGUIUtility.Load
首先会检查Unity工程中的”Assets/Editor Default Resources/ + path”中是否有Asset。如果有Asset的话,就会使用。如果没有的话,Build-in的AssetBundle中的Asset会被读取。