编辑器扩展总结
工欲善其事必先利其器
引言: 在项目开发中,编辑器扩展为开发者提供了开发自定义工具的功能,让开发者更加便利地使用编辑器开发项目。如若博客中存在错误,还请不吝赐教。所有参考的博客或者视频来源将在文末展示。
开发版本: Unity 2019.4.9f1
相关博客传送门
一、编辑器开发入门
八、EditorPrefs、ScriptableObject、Undo
创建编辑器窗体
Unity提供了几种可以创建编辑器窗体的方式,开发者可以针对不同使用情况来创建。
继承自ScriptableWizard类创建对话框窗体
Unity为开发者提供了一个简单的快速创建对话框窗体的方式,只需要继承自ScriptableWizard类,我们容易发现ScriptableWizard实际上是继承自EditorWindow,只是做了一层封装,该类窗体一般用于快捷功能的操作,例如统一修改场景中多个对象的位置等信息。
常用方法如下:
using UnityEngine;
using UnityEditor;
public class WindowExample1 : ScriptableWizard
{
public string msg = "";
//显示窗体
[MenuItem("MyWindow/First Window")]
private static void ShowWindow()
{
ScriptableWizard.DisplayWizard<WindowExample1>("WindowExample1", "确定", "取消");
}
//显示时调用
private void OnEnable()
{
Debug.Log("OnEnable");
}
//更新时调用
private void OnWizardUpdate()
{
Debug.Log("OnWizardUpdate");
if (string.IsNullOrEmpty(msg))
{
errorString = "请输入信息内容";//错误提示
helpString = "";//帮助提示
}
else
{
errorString = "";
helpString = "请点击确认按钮";
}
}
//点击确定按钮时调用
private void OnWizardCreate()
{
Debug.Log("OnWizardCreate");
}
//点击第二个按钮时调用
private void OnWizardOtherButton()
{
Debug.Log("OnWizardOtherButton");
}
//当ScriptableWizard需要更新其GUI时,将调用此函数以绘制内容
//为GUI绘制提供自定义行为,默认行为是按垂直方向排列绘制所有公共属性字段
//一般不重写该方法,按照默认绘制方法即可
protected override bool DrawWizardGUI()
{
return base.DrawWizardGUI();
}
//隐藏时调用
private void OnDisable()
{
Debug.Log("OnDisable");
}
//销毁时调用
private void OnDestroy()
{
Debug.Log("OnDestroy");
}
}
继承自EditorWindow类创建自定义窗体
创建自定义的编辑器窗体都需要继承自EditorWindow类,它可以自由浮动,也可以作为选项卡停靠,就像Unity编辑器中其他的窗体一样。编辑器窗体一般由菜单项打开,通常包含某一类的功能。作为一个编辑器类,需要放在Editor文件夹中。
官方API:EditorWindow
常用方法如下:
using UnityEngine;
using UnityEditor;
public class WindowExample2 : EditorWindow
{
private static WindowExample2 window;//窗体实例
//显示窗体
[MenuItem("MyWindow/Second Window")]
private static void ShowWindow()
{
window = EditorWindow.GetWindow<WindowExample2>("Window Example");
window.Show();
}
//显示时调用
private void OnEnable()
{
Debug.Log("OnEnable");
}
//绘制窗体内容
private void OnGUI()
{
EditorGUILayout.LabelField("Your Second Window", EditorStyles.boldLabel);
}
//固定帧数调用
private void Update()
{
Debug.Log("Update");
}
//隐藏时调用
private void OnDisable()
{
Debug.Log("OnDisable");
}
//销毁时调用
private void OnDestroy()
{
Debug.Log("OnDestroy");
}
}
继承自PopupWindowContent类创建弹窗
用于实现在编辑器中弹出窗口,弹窗类继承自PopupWindowContent类,当弹窗失去焦点时,就会自动关闭。
如下案例实现点击窗体内按钮,显示弹窗的功能。第一个脚本定义了一个可以通过按钮打开弹窗的编辑器窗口,第二个脚本将弹出窗口本身的内容定义为一个单独的类。
using UnityEngine;
using UnityEditor;
public class WindowExample3 : EditorWindow
{
private static WindowExample3 window;
private PopWindowExample popWindow = new PopWindowExample();
private Rect buttonRect;
//显示窗体
[MenuItem("MyWindow/Third Window")]
private static void ShowWindow()
{
window = EditorWindow.GetWindow<WindowExample3>("Window Example 3");
window.Show();
}
//绘制窗体内容
private void OnGUI()
{
GUILayout.Label("Popup example", EditorStyles.boldLabel);
if (GUILayout.Button("Popup Options", GUILayout.Width(200)))
{
PopupWindow.Show(buttonRect, popWindow);
}
//获取GUILayout最后用于控件的矩形
if (Event.current.type == EventType.Repaint)
buttonRect = GUILayoutUtility.GetLastRect();
}
}
public class PopWindowExample : PopupWindowContent
{
bool toggle = true;
//开启弹窗时调用
public override void OnOpen()
{
Debug.Log("OnOpen");
}
//绘制弹窗内容
public override void OnGUI(Rect rect)
{
EditorGUILayout.LabelField("PopWindow");
toggle = EditorGUILayout.Toggle("Toggle", toggle);
}
//关闭弹窗时调用
public override void OnClose()
{
Debug.Log("OnClose");
}
public override Vector2 GetWindowSize()
{
//设置弹窗的尺寸
return new Vector2(200, 100);
}
}