初识编辑器拓展

支持

  • 菜单栏选项
  • 菜单栏窗口
  • 面板式编辑器
  • 窗口式编辑器

unity editor是一个通用的编辑器,提供了unity内部对象的创建,预览,编辑的功能及可视化界面。 用于扩展editor的类需要放到名字为“Editor”的文件夹中,这个文件夹可以直接放到”Assets“文件夹下,也可以是项目目录任何文件夹下的子文件夹,比如”Assets/SkillSystem/Editor”。

原理

重新绘制画面,主要是通过重写OnGUI、OnInspectorGUI之类的函数来实现的。

这些函数是生命周期中的一员,具体看Unity生命流程图。

简单使用

对上面提出的支持进行简单实践。

菜单栏选项

菜单栏里添加“Tools > 打包工具”项。点击执行方法。

1
2
3
4
5
6
7
using UnityEditor;

[MenuItem("Tools/打包工具")]
public void OutputAB()
{
......
}

菜单栏窗口

菜单栏里添加“Example > 打包工具”项。点击跳出制作的窗口以及控件。

使用方法:

  1. 继承ScriptableWizard
  2. 调用ScriptableWizard.DisplayWizard函数可以快速创建这个向导窗口。这个向导窗口只支持小于或等于两个按钮的定制(即提供的消息响应函数只有两个按钮的)。显示的按钮名字通过ScriptableWizard.DisplayWizard函数传入。

ScriptableWizard的API中的消息响应函数:(当满足某些条件下执行这些函数)

OnWizardCreate :两个按钮事件中的一个,当传入ScriptableWizard.DisplayWizard函数中”createButtonName”参数对应的按钮被点击时调用。

OnWizardOtherButton:两个按钮事件中的一个,当传入ScriptableWizard.DisplayWizard函数中”otherButtonName”参数对应的按钮被点击时调用。

OnWizardUpdate:当向导窗口打开时或者用户改变窗口内容时都会被调用。一般会在这里显示帮助文字和进行内容有效性验证。也可以动态改变按钮状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using UnityEngine;
using UnityEditor;
using System.Collections;

public class ScriptableWizardButton : ScriptableWizard
{
public Transform firstObject = null;
public Transform secondObject = null;

[MenuItem("Example/Show OnWizardOtherButton Usage")]
static void CreateWindow()
{
ScriptableWizard.DisplayWizard("Click info to know the distance between the objects", typeof(ScriptableWizardButton), "Finish!", "Info");
}

void OnWizardUpdate()
{
if (firstObject == null || secondObject == null)
{
isValid = false;
errorString = "Select the objects you want to measure";
}
else
{
isValid = true;
errorString = "";
}
}
// Called when you press the "Info" button.
void OnWizardOtherButton()
{
float distanceObjs = Vector3.Distance(firstObject.position, secondObject.position);
EditorUtility.DisplayDialog(
"The distance between the objects is: " + distanceObjs + " Units",
"",
"Ok");
}
// Called when you press the "Finish!" button.
void OnWizardCreate()
{
EditorUtility.DisplayDialog("OnWizardCreate ", "", "Ok");
}
}

窗口式编辑器

菜单栏里添加“Window > MyEditorWnd”。点击打开窗口式面板。

使用方法:继承EditorWindow,重写“OnGUI”函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using UnityEngine;
using UnityEditor;

public class MyEditorWnd : EditorWindow
{
string myString = "Hello World";
bool groupEnabled;
bool myBool = true;
float myFloat = 1.23f;

// Add menu named "My Window" to the Window menu
[MenuItem("Window/MyEditorWnd")]
static void Init()
{
// Get existing open window or if none, make a new one:
MyEditorWnd window = (MyEditorWnd)EditorWindow.GetWindow(typeof(MyEditorWnd));
window.Show();
}

void OnGUI()
{
GUILayout.Label("Base Settings", EditorStyles.boldLabel);
myString = EditorGUILayout.TextField("Text Field", myString);
groupEnabled = EditorGUILayout.BeginToggleGroup("Optional Settings", groupEnabled);
myBool = EditorGUILayout.Toggle("Toggle", myBool);
myFloat = EditorGUILayout.Slider("Slider", myFloat, -3, 3);
EditorGUILayout.EndToggleGroup();
}
}

面板式编辑器

对于上面提到所有拓展方式中,第三种“面板式编辑器”是最常用的一种,单独开篇。

是在做什么?

是在将 EditorGUI 拓展在 Inspector 面板上。

EditorGUI 和 GUI 的用法几乎完全一致,目前来说前者多用于编辑器开发,后者多用于发布后调试编辑器。总之,它们都是起辅助作用的。 EditorGUI 提供的组件非常丰富,常用的绘制元素包括文本、按钮、图片和滚动框等。做一个好的编辑器,是离不开 EditorGUI 的。

至于EditorGUI 和 数据的交互,是借由一个继承了MonoBehaviour的脚本的数据字段实现的。

怎么用

常规使用方法:

  1. 首先得有一个MonoBehaviour常规脚本,我们取名为“Show.cs”,可以在内自定义一些字段比如Sprite、List之类的。
  2. 新建脚本,继承Editor类,标上[CustomEditor(typeof(Show))]标签当挂Showt脚本时就会显示这个编辑器,用来让编辑器和脚本互通。
  3. 对2中新建的脚本重写”OnInspectorGUI”函数,对自己扩展的组件的编辑界面进行定制。

以上示例代码见文章【工具篇:Odin 可视化编辑器】

Odin插件

文章【工具篇:Odin 可视化编辑器】