一:EditorWindow类
Editor类和EditorWindow类都继承自同一个基类:ScriptableObject,他们都可以针对某种脚本类来进行操作
EditorWindow类主要是对编辑器进行扩展,不需要指定脚本,是绘制独立的窗口
使用到的类:
——GUILayout:绘制各种2D控件,比如按钮、文本、可折叠列表,以及对它们的分组和排版
——EditorGUILayout:与GUILayout类似,但是提供更多的预定义控件
——GUIUtility:绘制自定义的2D控件,比如进度条、对话框、打开文件夹
——EditorGUIUtility:绘制自定义的2D控件,比如进度条、对话框、打开文件夹
重写OnGUI方法进行绘制
二:代码实现
——窗口Window
[MenuItem("工具栏层级")]private static void ShowWindow(){//第一种EditorWindow window = GetWindow(typeof(TestWindow), true, "测试窗口");//第二种EditorWindow window = CreateWindow<Cheat>("测试窗口");window.Show();window.Focus();}
——标签Label
private void OnGUI(){GUI.skin.label.fontSize = 20;GUI.skin.label.fontStyle = FontStyle.Bold;GUI.skin.label.alignment = TextAnchor.MiddleCenter;GUILayout.Label("测试窗口");GUILayout.Label(Resources.Load<Texture>("Resources文件夹下的图片路径")); }
Project目录下右键—Create—GUI Skin可以看到所有可修改的属性
——文本字段TextField
string txt;private void OnGUI(){txt = EditorGUILayout.TextField("输入文本:", txt);}
——密码字段PasswordField
string txt;private void OnGUI(){txt = EditorGUILayout.PasswordField("密码:", txt);}
——整数字段IntField、浮点数字段FloatField
int value_int;float value_float;private void OnGUI(){value_int = EditorGUILayout.IntField("输入整数:", value_int);value_float = EditorGUILayout.FloatField("输入浮点数:", value_float);}
——二维向量字段Vector2Field、三维向量字段Vector3Field
private Vector3 v3;private Vector3 v2;private void OnGUI(){v3 = EditorGUILayout.Vector3Field("三维向量", v3);v2 = EditorGUILayout.Vector2Field("二维向量", v2);}
——物体字段ObjectField
GameObject go;Camera camera;private void OnGUI(){go = (GameObject)EditorGUILayout.ObjectField("赋值物体", go, typeof(GameObject),true); camera = (Camera)EditorGUILayout.ObjectField("赋值相机", camera, typeof(Camera), true);}
——颜色字段ColorField
private Color color;private void OnGUI(){color = EditorGUILayout.ColorField("颜色", color);}
——标签字段TagField
private string tag;private void OnGUI(){tag = EditorGUILayout.TagField("tag", tag);}
——层级字段LayerField
private int layer;private void OnGUI(){layer = EditorGUILayout.LayerField("layer", layer);}
——按钮Button
private void OnGUI(){ if (GUILayout.Button("按钮")){//按下按钮后执行的方法}}
——多行文本TextArea
string txt;private void OnGUI(){GUILayout.BeginHorizontal();GUILayout.Label("输入文本:",GUILayout.MaxWidth(50));txt = EditorGUILayout.TextArea(txt, GUILayout.MaxHeight(50));GUILayout.EndHorizontal();}
——单选框Toggle
bool b;private void OnGUI(){b = EditorGUILayout.Toggle("单选框", b);}
——折叠列表Foldout
bool foldout;private void OnGUI(){foldout= EditorGUILayout.Foldout(foldout, "列表");if (foldout){EditorGUILayout.LabelField("姓名:XXX");EditorGUILayout.LabelField("手机号:XXXXXXXXXXX");EditorGUILayout.LabelField("微信:XXXXXXXX");}}
——开关组BeginToggleGroup/EndToggleGroup
GameObject go;string txt;bool b;private void OnGUI(){b = EditorGUILayout.BeginToggleGroup("开启区域", b);txt = EditorGUILayout.TextField("输入文本:", txt);go = (GameObject)EditorGUILayout.ObjectField("赋值物体", go, typeof(GameObject), true);EditorGUILayout.EndToggleGroup();}
——可选择文本SelectableLabel(用于需要复制的文本)
private void OnGUI(){EditorGUILayout.SelectableLabel("微信号:597094538");}
——滑动条Slider、整数滑动条IntSlider
int value_int;float value_float;private void OnGUI(){value_float = EditorGUILayout.Slider("滑动条", value_float, 1, 10);value_int = EditorGUILayout.IntSlider("滑动条", value_int, 1, 10);}
——字符串类型的弹出选择菜单Popup
private int index = 0;string[] values = { "value1", "value2", "value3" };private void OnGUI(){index = EditorGUILayout.Popup("选择", index, values);}
——枚举类型的弹出选择菜单EnumPopup
public enum Value{Value1,Value2,Value3,}private Value value;private void OnGUI(){value = (Value)EditorGUILayout.EnumPopup("选择", value);}
——整数类型的弹出选择菜单IntPopup
private int index = 0;string[] values = { "value1", "value2", "value3" };int[] value = { 1, 2, 3 };private void OnGUI(){index = EditorGUILayout.IntPopup("选择", index, values, value);EditorGUILayout.LabelField("value是:" + index);}
——设置绘制的方向BeginScrollView、EndHorizontal和BeginVertical、EndVertical
BeginScrollView和BeginVertical可以设置内置样式
private void OnGUI(){EditorGUILayout.BeginHorizontal();EditorGUILayout.EndHorizontal();}
——设置滑动区域BeginScrollView、EndScrollView
Vector2 scrollPos;private void OnGUI(){scrollPos = EditorGUILayout.BeginScrollView(scrollPos);EditorGUILayout.EndScrollView();}
——再次确认的对话框DisplayDialog
private void OnGUI(){if (GUILayout.Button("按钮", GUILayout.Width(50), GUILayout.Height(50))){if (EditorUtility.DisplayDialog("再次确定", "是否确定", "确定", "取消")){Debug.Log("yes");}}}
——进度条DisplayProgressBar
private void OnGUI(){if (GUILayout.Button("按钮")){int totalCount = Selection.gameObjects.Length;for (int i = Selection.gameObjects.Length - 1; i >= 0; i--){DestroyImmediate(Selection.gameObjects[i]);EditorUtility.DisplayProgressBar("进度条", "当前进度", totalCount - i / totalCount);}EditorUtility.ClearProgressBar();}}
——工具栏Toolbar
string[] values = { "Menu1", "Menu2", "Menu3" };private int index = 0;//string[] values = { "value1", "value2", "value3" };private void OnGUI(){index = GUILayout.Toolbar(index, values);if (index == 0){EditorGUILayout.LabelField("this is menu1");}else if (index == 1){EditorGUILayout.LabelField("this is menu2");}}
——显示提示信息ShowNotification
private void OnGUI(){if (GUILayout.Button("显示提示信息")){ShowNotification(new GUIContent("this is a Notification"));}if (GUILayout.Button("关闭提示信息")){RemoveNotification();}}
——显示帮助信息HelpBox
private void OnGUI(){EditorGUILayout.HelpBox("帮助信息", MessageType.None);EditorGUILayout.HelpBox("警告提示", MessageType.Warning);}
——选择文件/文件夹位置
private void OnGUI(){if (GUILayout.Button("选择存储位置")){path = EditorUtility.OpenFilePanel("选择文件", path, ".xls");dir = EditorUtility.OpenFolderPanel("选择路径", dir, "");}}
三:绘制一个自定义的Debug窗口
using UnityEditor;using UnityEngine;using UnityEngine.SceneManagement;using System.IO;public class DebugWindow : EditorWindow{[MenuItem("Tools/Show DebugWindow")]private static void ShowWindow(){GetWindow(typeof(DebugWindow), true, "Debug窗口", true);}int toolbarIndex;string[] toolbarStr = { "Error反馈窗口", "Warning反馈窗口" };bool haveError;bool haveErrorDes;string errorName;GameObject errorGo;string errorDes;string[] errorType = { "普通", "一般", "严重" };private int errorTypeIndex;string errorPath;private void OnGUI(){toolbarIndex = GUILayout.Toolbar(toolbarIndex, toolbarStr);if (toolbarIndex == 0){//标题标签GUI.skin.label.fontSize = 20;GUI.skin.label.fontStyle = FontStyle.Bold;GUI.skin.label.alignment = TextAnchor.MiddleCenter;GUILayout.Label("Error反馈窗口");haveError = EditorGUILayout.Toggle("是否有Error", haveError);if (haveError){//问题名errorName = EditorGUILayout.TextField("问题名", errorName);if (errorName != null){if (errorName.Length == 0 || errorName == ""){EditorGUILayout.HelpBox("问题名不能为空", MessageType.Error);}else if (errorName.Length >= 5){EditorGUILayout.HelpBox("问题名过长", MessageType.Warning);}else{EditorGUILayout.HelpBox("问题名合法", MessageType.Info);}}//出现问题的时间EditorGUILayout.LabelField("当前时间", System.DateTime.Now.ToString());//出现问题的场景EditorGUILayout.LabelField("当前场景", SceneManager.GetActiveScene().name);//出现问题的物体errorGo = (GameObject)EditorGUILayout.ObjectField("问题物体", errorGo, typeof(GameObject), true);//问题描述haveErrorDes = EditorGUILayout.BeginToggleGroup("是否添加问题描述", haveErrorDes);EditorGUILayout.BeginHorizontal();EditorGUILayout.LabelField("问题描述:", GUILayout.MaxWidth(50));EditorGUILayout.TextArea(errorDes, GUILayout.MaxHeight(50));EditorGUILayout.EndHorizontal();EditorGUILayout.EndToggleGroup();//问题类型errorTypeIndex = EditorGUILayout.Popup("问题类型", errorTypeIndex, errorType);//问题保存路径EditorGUILayout.BeginHorizontal();if (GUILayout.Button("选择路径")){errorPath = EditorUtility.SaveFolderPanel("Path to Save", errorPath, Application.dataPath);}EditorGUILayout.TextField(errorPath);EditorGUILayout.EndHorizontal();GUILayout.Space(50);//保存到本地if (GUILayout.Button("保存")){if (errorPath == null){ShowNotification(new GUIContent("请先选择保存路径"), 1);}else{Directory.CreateDirectory(errorPath + "/BugReports");StreamWriter sw = new StreamWriter(errorPath + "/BugReports/" + errorName + ".txt");sw.WriteLine("Error or Warning:" + toolbarStr[toolbarIndex]);sw.WriteLine("问题名:" + errorName);sw.WriteLine("出现问题的时间:" + System.DateTime.Now.ToString());sw.WriteLine("出现问题的场景:" + SceneManager.GetActiveScene().name);sw.WriteLine("问题描述:" + errorDes);sw.WriteLine("问题类型:" + errorType);sw.WriteLine("问题存储路径:" + errorPath);sw.Close();}}}}else if (toolbarIndex == 1){GUI.skin.label.fontSize = 20;GUI.skin.label.fontStyle = FontStyle.Bold;GUI.skin.label.alignment = TextAnchor.MiddleCenter;GUILayout.Label("Warning反馈窗口");//其他的与Error反馈窗口基本相同}}}