赞
踩
通常绘制EditorWindow需要手动一个个手动绘制控件和布局,但是联想到Inspector可以根据SerializedObject对象自动绘制和布局,那么如果我们可以根据SerializedObject对象来控制EditorWindow的显示,然后在此之上再进行一些自定义工作,岂不是会方便快捷很多。
本文将会介绍,如何使用ScriptableObject对象的Inspector绘制,来填充EditorWindow的界面显示。关于Inspector绘制介绍见这篇文章:自定义属性面板Inspector详解。
ScriptableObject对象可以运行时存储临时数据,也可以生成.asse文件持久化数据,如果ScriptableObject持久化对象对应一个EditorWindow窗口,刚好可以当做窗口配置数据源来使用。当然,ScriptableObject的asset文件本身拥有Inpsector编辑显示能力,可以单独用来保存数据使用。比如,建立如下一个ScriptableObject子类:
using UnityEngine; using System.Collections; // 生成入口到Unity菜单Assets->Create下 [CreateAssetMenu(menuName = "Create ShowObject")] public class ShowObject : ScriptableObject { public Vector3 position; [Space(20)] // 注意,ShowObject需要单独一个文件,并且文件名与类名一致,[]属性才能有效。 public string label; [Range(0, 10)] // 注意,ShowObject需要单独一个文件,并且文件名与类名一致,[]属性才能有效。 public int intData; public bool isCheck; public Options options; public Shader defaultShader; public enum Options { Opt1, Opt2, Opt3, } }
这样,我们就能够创建一个ShowObject的asset文件,而选中这个asset文件,就可以看到ShowObject的绘制和布局。我们就是需要把这个Inspector的显示,放入到EditorWindow之中绘制。
public class EditorWindows : EditorWindow
{
[MenuItem("ExtendingEditor/ShowObject Window")]
public static void ShowObjectWindow()
{
EditorWindow.GetWindow<EditorWindows>(true, "ShowObject Window", true);
}
private void OnGUI()
{
// 绘制ScriptableObject的Inspector显示,目前是空的。
}
}
有两种方法,来绘制ScriptableObject的内容:
首先,我们需要创建ScriptableObject对象,然后构建一个SerializedObject,接着遍历绘制SerializedObject的每一个Property。
public class EditorWindows : EditorWindow { private SerializedObject serializedObject; [MenuItem("ExtendingEditor/ShowObject Window")] public static void ShowObjectWindow() { var window = EditorWindow.GetWindow<EditorWindows>(true, "ShowObject Window", true); // 创建ScriptableObject并生成SerializedObject window.serializedObject = new SerializedObject(ScriptableObject.CreateInstance<ShowObject>()); } private void OnGUI() { this.serializedObject.Update(); var iterator = this.serializedObject.GetIterator(); // go to child iterator.NextVisible(true); // skip name iterator.Next(false); // skip EditorClassIdentifier iterator.Next(false); // 遍历每一个属性并绘制 while (iterator.Next(false)) { EditorGUILayout.PropertyField(iterator); } this.serializedObject.ApplyModifiedProperties(); } }
既然ScriptableObject有自己的Inspector绘制,那么我们就可以直接调用Inspector的Editor绘制,而不需要自己手动遍历SerializedObject的属性。
public class EditorWindows : EditorWindow { private Editor editor; [MenuItem("ExtendingEditor/ShowObject Window")] public static void ShowObjectWindow() { var window = EditorWindow.GetWindow<EditorWindows>(true, "ShowObject Window", true); // 直接根据ScriptableObject构造一个Editor window.editor = Editor.CreateEditor(ScriptableObject.CreateInstance<ShowObject>()); } private void OnGUI() { // 直接调用Inspector的绘制显示 this.editor.OnInspectorGUI(); } }
既然ScriptableObject有自己的Inspector的Editor绘制,那么我们就可以自定义扩展它,然后就可以直接显示在EditorWindows里面了。比如:
// 自定义ScriptableObject的Editor显示
[CanEditMultipleObjects, CustomEditor(typeof(ShowObject))]
public class ShowObjectEditor : Editor
{
}
当然,也可以使用PropertyDrawer和PropertyAttribute来进行扩展。
「简化自定义窗口工作」
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。