准备工作
在Unity工程中新建Editor文件夹存放编辑器脚本,
![](https://i-blog.csdnimg.cn/direct/a34e1a397cb3424eaac7d8a649380cf1.png)
Unity中其他的特殊文件夹可以参考官方文档链接,如下:
Unity - 手册:保留文件夹名称参考 (unity3d.com)
一、菜单栏扩展
1.增加顶部菜单栏选项
使用MenuItem,包含三个参数,官方文档描述如下:
![](https://i-blog.csdnimg.cn/direct/f01eb35c7cb04c8c8fb439e7d6f1d62d.png)
代码:
cs
[MenuItem("Tool/test")]
public static void test()
{
Debug.Log("test.....");
}
结果:
![](https://i-blog.csdnimg.cn/direct/a029e8c88e7a4826bad8d843383c28a1.png)
![](https://i-blog.csdnimg.cn/direct/ca56cfb895f84cf9b5352cb8566eab17.png)
2.增加右键Create菜单栏选项
使用MenuItem,ItemName需要从"Assets"开始,比如需要在Create菜单栏加一个testFolder的函数
代码:
cs
[MenuItem("Assets/Create/testFolder")]
public static void test2()
{
Debug.Log("test2....");
}
结果:
![](https://i-blog.csdnimg.cn/direct/2e48858595a5406fa60c85c4c104d126.png)
![](https://i-blog.csdnimg.cn/direct/8c480f8677f945e2b86300970fff25c0.png)
更多Unity支持的编辑器特性,可查看官方API,地址:
CustomGridBrushAttribute - Unity 脚本 API
![](https://i-blog.csdnimg.cn/direct/f5aa101d7a214d1b822b1336e49b4a85.png)
3.使用快捷键
官方文档的MenuItem中使用快捷键描述如下:
![](https://i-blog.csdnimg.cn/direct/247e59c50eac486a9caa9cf183f984bd.png)
官方文档链接:
Unity - 脚本 API:MenuItem (unity3d.com)
热键文本之前必须有一个空格字符:
代码:
cs
[MenuItem("Tool/testHotKey0 _g")]
public static void testHotKey0()
{
Debug.Log("testHotKeytestHotKey0..........");
}
结果:
![](https://i-blog.csdnimg.cn/direct/cdd7a75b62b34133a354afe929c69d57.png)
![](https://i-blog.csdnimg.cn/direct/169ecc3ea041449aaea2327ed0c0bb4b.png)
如果不需要特殊的修饰键组合,则可以在下划线后给出键:
代码:
cs
[MenuItem("Tool/testHotKey #g")]
public static void testHotKey()
{
Debug.Log("testHotKeytestHotKey..........");
}
[MenuItem("Tool/testHotKey1 #&g")]
public static void testHotKey1()
{
Debug.Log("testHotKeytestHotKey1..........");
}
结果:
![](https://i-blog.csdnimg.cn/direct/e84c3f5db03e4eb89223b3e24d807e37.png)
![](https://i-blog.csdnimg.cn/direct/963f736d652c48c895fd3c48886dc922.png)
支持将一些特殊的键盘键(LEFT, RIGHT, UP, DOWN, F1 ..F12、HOME、END、PGUP、PGDN、INS、DEL、BACKSPACE、TAB 和 SPACE)作为热键:
代码:
cs
[MenuItem("Tool/testHotKey2 #LEFT")]
public static void testHotKey2()
{
Debug.Log("testHotKeytestHotKey2..........");
}
结果:
![](https://i-blog.csdnimg.cn/direct/99d976ea04f84ac0a071a9b8476f727e.png)
![](https://i-blog.csdnimg.cn/direct/373f0be32c2b47d0939b5cd3475f8b1e.png)
4.弹出一个提示窗口
使用EditorUtility.DisplayDialog显示窗口,第一个参数是弹窗名,第二个参数是提示内容,第三个参数是按钮名字
代码:
cs
[MenuItem("Tool/testDialog")]
public static void DisplayDialog()
{
EditorUtility.DisplayDialog("Tips", "Hello World", "Completely");
}
结果:
![](https://i-blog.csdnimg.cn/direct/4fd21a73b4f84de0aae0bdf8042ebfbc.png)
二、自定义窗口扩展
1.创建自定义窗口
自定义窗口需要创建的窗口脚本继承子EditorWindow,然后在OnGUI中渲染窗口的实际内容,
新建一个TestWindow脚本,代码如下:
cs
public class TestWindow : EditorWindow
{
private void OnGUI()
{
//渲染窗口的实际内容
}
}
编写打开窗口的函数,代码如下:
cs
[MenuItem("CustomWindow/ShowTestWin")]
public static void ShowWindow()
{
//显示窗口实例
//EditorWindow.GetWindow(typeof(TestWindow));
//显示窗口按照自定位置和大小,比如(0,0)点,宽600,长800
EditorWindow.GetWindowWithRect<TestWindow>(new Rect(new Vector2(0,0),new Vector2(600,800)));
}
结果:
![](https://i-blog.csdnimg.cn/direct/9a45dc432da041c2b02c2c685b838058.png)
![](https://i-blog.csdnimg.cn/direct/91799c12f54f40ff9187540af76a0623.png)
EditorWindow类中的方法:
官方文档描述如下:
![](https://i-blog.csdnimg.cn/direct/a3b3f6caba83485cb3fcee9d0b98357b.png)
更多方法可参考:Unity - 脚本 API:EditorWindow (unity3d.com)
代码:
cs
public class TestWindow : EditorWindow
{
[MenuItem("CustomWindow/ShowTestWin")]
public static void ShowWindow()
{
//显示窗口实例
EditorWindow.GetWindow(typeof(TestWindow));
//显示窗口按照自定位置和大小,比如(0,0)点,宽600,长800
EditorWindow.GetWindowWithRect<TestWindow>(new Rect(new Vector2(0,0),new Vector2(600,800)));
}
private void OnEnable()
{
//在加载脚本或者启用对象时调用
Debug.Log("OnEnable");
}
private void CreateGUI()
{
//如果Editor未更新,则生成图形用户界面
Debug.Log("CreateGUI");
}
private void Update()
{
//每帧调用一次以更新脚本的逻辑
Debug.Log("Updaete");
}
private void OnDisable()
{
//当脚本被禁用或者对象被销毁以完成和清理资源时调用
Debug.Log("OnDisable");
}
private void OnGUI()
{
//每帧多次调用,用于渲染和处理GUI事件
//渲染窗口的实际内容
Debug.Log("OnGUI");
}
}
结果:
![](https://i-blog.csdnimg.cn/direct/d4a8e65acc424bf08ca13686fc1e7bda.png)
2.增加窗口内容
1.使用EditorGUI类
1.actionKey
![](https://i-blog.csdnimg.cn/direct/ed5f8bae0c504c3aa20a1bb1e0b9dade.png)
使用代码:
cs
private void OnGUI()
{
//渲染窗口的实际内容
if (EditorGUI.actionKey)
{
//是否按住了平台相关的"action"修改键?(只读),该键在 macOS 上为 Command,在 Windows 上为 Control
Debug.Log("按下了actionKey");
}
}
结果:
![](https://i-blog.csdnimg.cn/direct/ecb558676a5a499f98fcc0c68b8b9923.png)
2.indentLevel
![](https://i-blog.csdnimg.cn/direct/08bc66abc53b4d899023db06d222d61e.png)
使用代码:
cs
private void OnGUI()
{
//渲染窗口的实际内容
//使用indentLevel缩进文本
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("P1:");
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("P2:");
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("P3:");
EditorGUI.indentLevel--;
EditorGUI.indentLevel--;
EditorGUILayout.LabelField("P1:");
EditorGUI.indentLevel++;
EditorGUILayout.LabelField("P2:");
}
结果:
![](https://i-blog.csdnimg.cn/direct/d13be79e7e0b479a911d66a3e4fa54e0.png)
3.showMixedValue
![](https://i-blog.csdnimg.cn/direct/f967b38dd1434af2990ad4467c3a023a.png)
具体作用可以看下面两篇文章
EditorGUI.showMixedValue 什么都不做?- Unity 引擎 - Unity 讨论
Unity - 脚本 API:EditorGUI.showMixedValue (unity3d.com)
就是可以让在 GUI 中以非标准方式表示值,同时支持多对象编辑,也就是通过设置此值为true,让枚举值没有在面板选择值时显示为
代码:
cs
private void OnGUI()
{
//渲染窗口的实际内容
EditorGUI.showMixedValue = true;
// 将isFast布尔值转换为enum值
SpeedOption speedOptionEnumValue = SpeedOption.Fast;
// 在下拉菜单中显示枚举值:
speedOptionEnumValue = (SpeedOption)EditorGUILayout.EnumPopup("Speed", speedOptionEnumValue);
// 将showMixedValue设置为false,这样它就不会影响以下控件(如果有的话):
EditorGUI.showMixedValue = false;
}
结果:
![](https://i-blog.csdnimg.cn/direct/3685bc5486314d9ba9ff3d30f1fb5bd8.png)
4.BeginChangeCheck,EndChangeCheck
![](https://i-blog.csdnimg.cn/direct/adbffd30a969404286f03f493a61b6db.png)
EndChangeCheck返回值如下
代码:
cs
float value = 0;
private void OnGUI()
{
//渲染窗口的实际内容
EditorGUI.BeginChangeCheck();
value = EditorGUILayout.Slider(value, 0, 1);
if (EditorGUI.EndChangeCheck())
{
this.ShowTips("变量检查成功!");
}
}
结果:
![](https://i-blog.csdnimg.cn/direct/734cfca6621443e78ae1d420265687e1.png)
5.BeginDisabledGroup,EndDisabledGroup
BeginChangeCheck参数如下:
![](https://i-blog.csdnimg.cn/direct/a3b3d92a760b4af8b6ba727c3c477d05.png)
使用这两个API可以禁用执行在其中间的多个组件。
代码:
cs
private void OnGUI()
{
//渲染窗口的实际内容
EditorGUI.BeginDisabledGroup(false);
EditorGUI.TextField(new Rect(new Vector2(0,150),new Vector2(300,50)), "TestDisabledGroup");
EditorGUI.DropdownButton(new Rect(new Vector2(300, 150), new Vector2(100, 50)),this.titleContent,FocusType.Keyboard);
EditorGUI.EndDisabledGroup();
}
结果:
当BeginDisabledGroup传入值为false时,
![](https://i-blog.csdnimg.cn/direct/cad95379b849467ca659d42b1e92dc87.png)
当BeginDisabledGroup传入值为true时,
![](https://i-blog.csdnimg.cn/direct/5c28175007c74f09b31477d59a576c5e.png)
6.BeginFoldoutHeaderGroup,EndFoldoutHeaderGroup
![](https://i-blog.csdnimg.cn/direct/bc5efe65e6f9416bbdb726eeae3f4507.png)
BeginFoldoutHeaderGroup参数如下:
![](https://i-blog.csdnimg.cn/direct/780ed8d6fa5e45e4bfd4e89784c598aa.png)
代码:
结果:
7.BeginProperty,EndProperty
8.文本字段(Field)
以下API都是在面板中创建一个字段显示,故放在一起整理:
BoundsField
BoundsIntField
ColorField
CurveField
EnumFlagsField
DoubleField
FloatField
IntField
LabelField
![](https://i-blog.csdnimg.cn/direct/d8584ccc59f149f2a62904180621d674.png)
LayerField
GradientField
LongField
MaskField
MultiFloatField
MultiIntField
MultiPropertyField
ObjectField
PasswordField
PropertyField
RectField
RectIntField
TagField
TextField
Vector2Field
Vector2IntField
Vector3Field
Vector3IntField
Vector4Field
使用代码:
9.DelayedDoubleField,DelayedFloatField,DelayedIntField,DelayedTextField
10.CanCacheInspectorGUI
11.DrawPreviewTexture
12.DrawRect
13.DrawTextureAlpha
14.DropdownButton
15.DropShadowLabel
16.EnumPopup,IntPopup,Popup
17.FocusTextInControl
18.Foldout
19.GetPropertyHeight
20.HandlePrefixLabel
21.HelpBox
22.InspectorTitlebar
23.IntSlider
24.LinkButton
25.MinMaxSlider
26.PrefixLabel
27.ProgressBar
28.SelectableLabel
29.Slider
30.TextArea
31.Toggle,ToggleLeft
2.使用EditorGUILayout类
与EditorGUI不相同的API部分:
相同的部分:
三、自定义Inspectors面板扩展
1.建立一个脚本面板扩展的编辑器脚本
2.EditorGUILayout与EditorGUI部分与上面的使用相同
未完待续。。。
参考:
《Extending Unity with Editor Scripting》