Unity3D的运行时和编辑器类分别存储在不同的Assemblies里:UnityEngine和UnityEditor。由于编辑器插件是独立于游戏之外的,因此需要在assets文件夹下建立Editor目录来存放自定义插件的代码。需要注意的是Editor文件夹是被编辑器智能识别的,可以是其他文件夹的子文件夹,并且可以存在多个,这样就给我们安排文件结构提供了便利。注意游戏中的脚本是不能访问Editor文件夹下的代码的。
准备开始编写编辑器之前,需要using UnityEditor来导入编辑器的名称空间。顺便一说,Editor文件夹下的代码应该也是在这个名称空间里的。
如何开启自定义插件窗口
一般的插件都是需要交互窗口的(也有不需要的),一般写一个静态方法打开插件窗口,并在该静态方法前加上编辑器自定义的几种特性之一,进入的方法有有以下两种:
[MenuItem(path)]:告知编译器给Unity3D编辑器添加一个菜单项,并且当点击该菜单项的时候调用该函数。触发函数里可以编写任何合法的代码,可以是一个资源批处理程序,也可以弹出一个编辑器窗口。代码里可以访问到当前选中的内容(通过Selection类),并据此来确定显示视图。
[ContextMenu(“path”)]:可以向你的上下文菜单中添加一个菜单项,点击该菜单项时显示视图。
如何编辑自定义插件窗口
编写自定义的窗口界面,需要编写一个继承自EditorWindow的类。通常需要写一个[MenuItem]来告知编译器何时打开这个面板。这个方法可以返回void,在方法内可以使用EditorWindow.GetWindow<T>();来打开界面,T即插件类本身。同时在这个插件类中需要有OnGUI()方法,在此方法中绘制界面即可。
除了OnGUI外,还可以使用以下回调来触发某些具体的事件:
OnSelectionChange,但你点选物品时触发
OnFocus /OnLostFocus,获得和失去焦点时触发
OnDestroy:窗口被关闭时触发
OnHierarchyChange:当层级视图被改变时触发
OnInspectorUpdate:当监视器面板更新时触发
Update: 每秒100次被触发
除了继承EditorWindow之外,还可以继承自ScriptableWizard类来实现向导式窗口的编写,注意ScriptableWizard本身是继承自EditorWindow类的,所以它们的用法类似。不过注意,当点击确认按钮时,OnWizardCreate()会被调用。另外,ScriptableWizard.DisplayWizard()可以生成并显示出该窗口。
编写窗口内元素
一般游戏内的插件,比如技能编辑器,导出bundle包等的功能使用unity自带的UI建议方式即可,主要用到以下几个类:GUI,GUILayout,EditorGUILayout,EditorUtility。
GUI类是系统自带的UI生成类,可以生成各种基础元素如window,toggle,label,button等。
GUILayout布局类,中包括了最常用的几种功能比如BeginArea,BeginHorizontal,BeginVertical,BeginScrollView以及相应的End方法,是按照自动布局的方式快捷生成界面UI的。也有Button,Label等常用控件可通过该类快速生成。
EditorGUILayout是GUILayout的补充,里面有一些更复杂的控件,如Toggle,TextField,Slider,IntField,IntPopup,EnumMaskField,TagField等。还有其他的一些自动布局方法,如BeginScrollView,BeginFadeGroup,BeginToggleGroup等。
EditorUtility则是一些编辑器实用方法,如显示工作进度的DisplayProgressBar;打开保存路径RevealInFinder;显示弹出界面DisplayPopupMenu;替换预设ReplacePrefab等实用的方法。注意SetDirty也在此类中,这个函数是告诉编辑器哪个东西被修改了,如果是序列化的数据编辑器就会将修改后的数据保存起来。
除了以上几个编辑界面时需要用的类之外,还有一些实用的类和方法在编写自定义插件的时候也会用到:
Selection,这个类主要是获取目前用户的选中对象;
Application,应用相关方法,可以获得各种当前状态,还可以使用logMessageReceived注册新log产生时的回调方法。
GUI .GetNameOfFocusedControl () : 获取控件是否处于焦点状态。
一些需要挂在才能生效的Component脚本,会需要用到下面的特性:
[ExecuteInEditMode]通知编译器,该类的OnGUI和Update等函数在编辑模式也也会被调用。
[AddComponentMenu(“XXX/XXX”)]:把脚本关联到Component菜单中,点击相应菜单项即可为选中的GameObject添加该脚本。
最后是一个简单的例子,用来整体缩放UI控件(其中的UISprite是NGUI中的组件):