Unity编辑器

Unity编辑器

这篇文章主要总结一下最近工作时写的一些编辑器,总结了三种常用的编辑器编写方式:

Inspector Editor

利用CustomEditor特性挂接Script来实现Inspector界面显示

InspectorEditorImage

首先我们给出对应的Script代码,主要是为了提供Inspector面板的参数而用

1
2
3
4
5
6
7
8
public class SampleEditorScript : MonoBehaviour
{
public int sliderNum = 0;
public int intNum = 0;
public float floatNum = 0f;
public string str = "";
public Vector2 pos = Vector2.zero;
}

之后写对应的Editor文件

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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// 脚本为前面编写的数据脚本
[CustomEditor(typeof(SampleEditorScript))]
// [CanEditMultipleObjects] 多对象编辑
public class SampleEditor : Editor
{
SerializedProperty sliderNum;
SerializedProperty intNum;
SerializedProperty floatNum;
SerializedProperty str;
SerializedProperty pos;

void OnEnable()
{
// 将值传给对应的SerializedProperty
sliderNum = serializedObject.FindProperty("sliderNum");
intNum = serializedObject.FindProperty("intNum");
floatNum = serializedObject.FindProperty("floatNum");
str = serializedObject.FindProperty("str");
pos = serializedObject.FindProperty("pos");
}

/// <summary>
/// 绘制Inspector窗口
/// </summary>
public override void OnInspectorGUI()
{
// 每次绘制insperctor面板的时候都应该更新一下serializedObjectd的数据
serializedObject.Update();

// 除PropertyField函数外,正常函数也封装了传入SerializedProperty的用法
EditorGUILayout.IntSlider(sliderNum, 0, 100, new GUIContent("Slider"));
ProgressBar(sliderNum.intValue / 100.0f, "Slider Num");

// PropertyField好处为自动识别类型
EditorGUILayout.PropertyField(intNum, new GUIContent("Int Num"));
EditorGUILayout.PropertyField(floatNum, new GUIContent("Float Num"));
EditorGUILayout.PropertyField(str, new GUIContent("string"));
EditorGUILayout.PropertyField(pos, new GUIContent("Vector2"));

// 将数据更改应用于serializedObject
serializedObject.ApplyModifiedProperties();
}

/// <summary>
/// 绘制Scene窗口
/// </summary>
void OnSceneGUI()
{
// 绘制的线为红色
Handles.color = Color.red;
// 在点(0,0,0)到(1,1,1)画一条红线
Handles.DrawLine(Vector3.zero, Vector3.one);
}

/// <summary>
/// 自定义进度条
/// </summary>
/// <param name="value">进度条值</param>
/// <param name="label">进度条名字</param>
void ProgressBar(float value, string label)
{
// 为文本框绘制一个进度条
Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
EditorGUI.ProgressBar(rect, value, label);
EditorGUILayout.Space();
}
}

EditorWindow

创建一个编辑器视窗,视窗可以内嵌到Unity编辑器中

EditorWindowImage

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
public class SampleEditorWindow : EditorWindow
{
private int intNum = 0;
private float floatNum = 0f;
private string str = "";
private Vector2 SVPos;

/// <summary>
/// 菜单栏响应函数
/// </summary>
[MenuItem("EditorTools/SampleEditorWindow")]
static void Init()
{
// 初始化窗口并显示
SampleEditorWindow window = (SampleEditorWindow)GetWindow(typeof(SampleEditorWindow));
window.Show();
}

/// <summary>
/// 界面绘制函数
/// </summary>
void OnGUI()
{
// 绘制可用EditorGUILayout、GUILayout所提供的函数等

// 竖直排版
EditorGUILayout.BeginHorizontal();
// 滑动组件
SVPos = EditorGUILayout.BeginScrollView(SVPos);
// int输入框
intNum = EditorGUILayout.IntField("Int Num", intNum);
// float输入框
floatNum = EditorGUILayout.FloatField("Float Num", floatNum);
// string输入框
str = EditorGUILayout.TextField("string", str);
// 等等...
EditorGUILayout.EndScrollView();
EditorGUILayout.EndHorizontal();
}
}

ScriptableWizard

创建一个编辑器导航视窗

ScriptableWizardImage

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
public class SampleScriptableWizard : ScriptableWizard
{
public int intNum = 0;
public float floatNum = 0f;
public string str = "";

[MenuItem("EditorTools/SampleScriptableWizard")]
static void Init()
{
ScriptableWizard.DisplayWizard<SampleScriptableWizard>("Wizard界面", "Wizard按钮", "Wizard另一个按钮");
}

/// <summary>
/// 界面的刷新
/// </summary>
void OnWizardUpdate()
{
helpString = "这是一条提示语句";
}

/// <summary>
/// 按钮执行功能
/// </summary>
void OnWizardCreate()
{
Debug.Log("点击按钮");
}

void OnWizardOtherButton()
{
Debug.Log("点击另一个按钮");
}
}