一、简介

以前一直以为Unity编辑器开发很复杂,很难。但是自学了一天之后,慢慢的将一些脚本用Editor来进行封装,发现在整体开发上会方便很多,很多数据、参数可以进行灵活查看以及屏蔽,所以特意做一个Editor的详细教程,分享给别人。

我将详细介绍Editor Windows(窗口)开发、Editor Inspector(属性窗口)开发、Editor Hierarchy(右键菜单)开发。

二、Windows窗口开发

先看效果图(关于读写Json的信息排版)

  1. 创建一个Editor脚本
    在Editor文件夹下新建一个类(TestEditorWindows),该类集成EditorWindow,还需要引用UnityEditor命名空间。
  2. 了解一些Windwos窗口开发的方法
    创建类完毕之后,在编写如下代码:
 //1.必须跟类型一样,这是窗口的名称TestEditorWindows(){this.titleContent = new GUIContent("测试编辑器窗口");}//2.这是在哪里创建窗口[MenuItem("Test/Test窗口")]static void CreateTestWindows(){EditorWindow.GetWindow(typeof(TestEditorWindows));}



目前窗口中什么都没有,因为我们还没开始写控件。
如果需要在窗口中绘制控件,则需要在OnGUI()中去编写相关代码,在此之前我们需要了解OnEnable()方法。

 //窗口启动时,会调用此方法private void OnEnable(){//OnEnable()方法是一个比较重要的方法,在一般的窗口绘制中,可在这里进行相关数据的初始化。}//实时绘制相关控件private void OnGUI(){//OnGUI()方法则是实时的进行控件绘制,窗口控件绘制也就在这里进行代码编写。}
  • 了解一些常用的控件了解一些常用的控件
    在编写想要的窗口时,需要了解常用的控件,这些控件都是我们非常常用的。值得注意的是不管是在Windows窗口开发还是Inspector窗口开发,常用的控件基本都在GUILayout和EditorGUILayout这两个类中,有些控件两者都可以,不过一般都会用EditorGUILayout,因情况而定……所以别在开发中,网上的资料中有时用GUILayout,有时又用EditorGUILayout。

下面将介绍常用的控件

  • GUILayout.BeginScrollView/GUILayout.EndScrollView

    GUILayout.BeginScrollView/GUILayout.EndScrollView这个控件是添加窗口滚动条的,也就是给你这个窗口添加水平和垂直滚动条。
    具体使用如下:

 Vector2 scrollPos = Vector2.zero; //当前滚动坐标//实时绘制相关控件private void OnGUI(){//参数一:滚动坐标//参数二:窗口宽度(position.width)//参数三:窗口高度(position.height)//其中position是内置的参数。scrollPos = GUILayout.BeginScrollView(scrollPos, GUILayout.Width(position.width), GUILayout.Height(position.height));GUILayout.EndScrollView();}

备注:编写完毕之后,此时看窗口是没有滚动条的样式的,因为里面目前还没有任何的控件。

在介绍后面两个控件时,我们需要说明下,在Unity编辑器中,如果我们要对控件进行控件的布局,比如有些控件水平显示,有些垂直显示。那么就需要应用后面的这两个控件,不过在一些真正的项目开发或者一些公司中,他们都会基于这两个布局控件,进行在封装一层,以方便灵活使用。在程序UI界中,比如UGUI、GUI、以及一些非Unity的UI控件插件等,都基本上有这种类似的布局。

需要注意:这种布局控件,一般都是配对出现的,比如你用了GUILayout.BeginVertical()后,在后面你必须要有GUILayout.EndVertical()。否则窗口将绘制不出来并且提示错误提示。这点在编写复杂的窗口时,很重要,因为一不留神就出现错误。最好在编写代码的时候,将BeginVertical和EndVertical一起码出来,以便到时候去匹配。

  • GUILayout.BeginVertical/GUILayout.EndVertical
    该控件是垂直布局控件,也就是说在这个区域内的控件,都将垂直排列。
  • GUILayout.BeginHorizontal/GUILayout.EndHorizontal
    该控件是水平布局控件,在这个区域内的控件,都将水平排列。
     //水平布局控件GUILayout.BeginHorizontal();GUILayout.Label("水平信息");if (GUILayout.Button("水平按钮")){}GUILayout.EndHorizontal();//空行(如果是在垂直布局内,就是垂直空50单位,反之如果在水平布局内,就水平空50单位)GUILayout.Space(50);//垂直布局控件GUILayout.BeginVertical();GUILayout.Label("垂直信息");if (GUILayout.Button("垂直按钮")){}GUILayout.EndVertical();


在这里在来一个小技巧,给布局添加背景样式,以及定义宽高,这时候就可以显示窗口滚动条了。



备注:当窗口缩放到代码指定的控件宽高时,窗口会自动显示滚动条,当然前提是你在最开始前布局了GUILayout.BeginScrollView/GUILayout.EndScrollView

  • GUILayout.Button:按钮
    Button按钮这个控件应该不需要进行介绍了,当按下时,返回true。可在这里写自己的实现,同时可设置Button的宽高,利用GUILayout.Width和GUILayout.Height,也可以利用GUIContent给按钮添加提示,同时可利用GUIStyle给按钮添加样式。
     if (GUILayout.Button(new GUIContent("水平按钮","鼠标移入时,提示信息"),GUI.skin.button,GUILayout.Width(50),GUILayout.Height(21))){//按下时的处理}
  • GUILayout.Box:Box区域
    Box控件就是文字框/图片框了,指定一块框,其实跟Button差不多,只不过不能进行点击而已。

  • EditorGUILayout.LabelField:文本信息
    LabelField控件,就是文本标签了,在这里可以书写自己的信息,没什么好介绍的。

  • GUILayout.HelpBox:帮助信息
    HelpBox类似LabelField标签,也是文字提示类的,但是它多了几个状态以及背景框,选择不同的状态显示不同的UI。

     //MessageType.Node:无//MessageType.Info:提示//MessageType.Warning:警告//MessageType.Error:错误//提示信息,用于提示警告、错误等EditorGUILayout.HelpBox("这是提示信息", MessageType.Error, true);

  • TextArea:文本输入框
 info = GUILayout.TextArea(info, GUILayout.Width(500), GUILayout.Height(50));//在窗口中绘制一个文本输入框。
  • Toggle:单选框
    Toggle控件一般用于接收Bool参数,比如你有一个Bool值参数,需要在窗口中显示出来,那么用Toggle可帮你接收到这个Bool值信息,这个也不需要什么介绍。

  • Slider:进度条
    Slider控件,提供一个滑轮,指定最大值、最小值。那么可滑动来设置这些值,同时也可以手动设置,类似MonoBehaviour中的Range特性。

  • EditorGUILayout.EnumPopup:枚举框
    枚举控件也是在编写编辑器中,使用的比较多的,比如选择不同的枚举,绘制出来的控件都是不一样的,这种情况在我们写脚本的时候,可能要定义很多属性,然后在Inspector属性窗口中,一下子全部都列出来了,但是我们只想根据不同的状态,显示一部分需要的。枚举框、Toggle等控件就有用武之力了,我在编写编辑器时,经常会用到枚举或Toggle,让Inspector属性绘制出来的窗口变得简介明了,方便别人使用。

    如下图所示:
    这是我基于UGUI在往上封装一层的KGUI控件,这是其中的一个Toggle控件(提前说明下,后续的博客更新,我将详细的介绍我的KGUI控件,同时会详细讲解UGUI的内部一些知识,并且还会开源的哦,里面集成了类似Excel表格控件、背包、滚动条、Button、下拉框等,都是基于UGUI的RectTransform组件和Image组件,重新编写一套适合自己项目开发的控件集等等

 //枚举类public enum TestType{A,B,C,D}//在方法外定义一个枚举对象private TestType testType = TestType.A;//下面的代码是在OnGUI下绘制的testType = (TestType)EditorGUILayout.EnumPopup(new GUIContent("枚举值:", "枚举的详细提示信息"), testType);
  • DropdownButton:下拉框
    DropdownButton可能大家不了解,也许会用不到,它的效果跟EnumPopup,不过EnumPopup是基于枚举类,序列化出来的,而DropdownButton是根据自定义添加子项。
 //外部String变量,用于接收下拉框值private string itemStr = "";//方法类的核心代码//其中new GUIContent(itemStr),用于接收当前选中的值if (EditorGUILayout.DropdownButton(new GUIContent(itemStr), FocusType.Keyboard)){var alls = new string[4]{"A","B","C","D"};GenericMenu menu = new GenericMenu(); //实例化一个菜单//遍历字符串集合foreach (var all in alls){if (string.IsNullOrEmpty(all)) continue;//添加子项AddMenuItemForValue(menu, all);}menu.ShowAsContext();//绘制出菜单}//添加子项void AddMenuItemForValue(GenericMenu menu, string value){//添加子项的格式,itemStr.Equals(value)如果与目前相等的,就处于选中状态menu.AddItem(new GUIContent(value), itemStr.Equals(value),OnValueSelected, value);}//当选中某个值的时候,itemStr获取到选中值void OnValueSelected(object value){itemStr = value.ToString();}

  • EditorGUILayout.ObjectField 序列化Object物体
    EditorGUILayout.ObjectField组件是用于显示一些针对继承UnityEngine.Object类的相关组件,比如GameObject、Transform、Component等相关组件,或者继承MonoBehaviour类的脚本。这个控件在编写编辑器时,也是经常会用到的一个东西。
 target = EditorGUILayout.ObjectField(new GUIContent("信息:", "鼠标移入到这个控件时,显示的提示信息"), target, typeof(GameObject), true) as GameObject;


值得注意的是,在Inspector属性编辑器开发中,有EditorGUILayout.PropertyField组件,它的作用作用跟ObjectField控件是一样的,只不过在窗口中,或者有些情况下EditorGUILayout.PropertyField没那么方便,但是在Inspector属性开发中会方便很多。后续在详细介绍它。

  • GUIContent:控件文字提示
    GUIContent也是一个非常常用的东西。给绘制的控件加别名与提示信息,在Inspector属性绘制中,有一些英文属性也许看名字不了解他是什么作用,但是如果用这个绘制出来,就可以很方便它的作用了。大部分控件都可以用这个,当然也有一些控件是不能用这个的。

  • GUIStyle控件样式
    GUIStyle则是控件的样式,比如Label的字体大小,颜色等等。一般采用系统默认的,这个根据自身情况而定采用自定义的。

  • 根据数据进行配置
    明白上述所有的控件之后,就可以在EditorWindows窗口进行绘制自己想要的控件了,再结合GUILayout.BeginHorizontal等相关布局控件,就可以绘制去自己想要的编辑器。

  • 其他控件
    还有一些其他的控件,就不一一列了,基本都是大同小异。
    这是根据这些基本控件,以及一些数据类,具体实现等进行自定义绘制一个配置Json文件的窗口化,可以很方便的对Json进行增删改查。

    如果大家看到这里有疑问的,请不要在博客中回复,因为我很少看博客的评论的,可加入我的个人公众号(Hua灬清),我会每周更新一篇博客文档同步公众号文章。

三、Inspector属性开发

  • 简介
    Inspector针对脚本进行编辑器绘制,所用的控件跟Windows窗口开发基本一致,只不过一些绘制方法、初始化等有所区别,下面我将不详细的介绍基本控件了,如果不理解的可以看【Windows窗口开发】这一节。
    我们以下述KGUI_Button类进行Inspector属性绘制。

  • KGUI_Button类介绍
    KGUI是本人根据UGUI操作的局限性,基于UGUI的Image组件和RectTransform、Canvas这三个组件,进行了二次封装,后续博客我会详细的介绍KGUI里面的一些组件,同时会介绍UGUI一些比较深的知识。

    KGUI_Button类也就是类似UGUI的Button,提供了一些常用的事件,同时也提供了针对物体的按钮出发,因为在实际项目开发中,可能美术提供的UI是特效,那么我们知道UGUI中使用特效Button是比较麻烦的,所以一般有些时候会用SpriteRenderer,同时又有些情况Button需要声音,以及按钮的激活、选中组等等很多情况,那么UGUI的Button可能满足不了那么多情况,但同时这些功能又有时候是通用的,所以抛离UGUI的Button,基于射线和碰撞体去开发一套全新的,类似我们熟悉的NGUI。

    重点介绍KGUI_Button的相关属性,不介绍具体的方法实现和类设计,因为这篇不讲解具体实现,重点关注编辑器开发,属性讲解只是辅助手段。

  • 属性

     public ButtonType buttonType;public SpriteRenderer spriteRenderer;public Image image;public Sprite normalSprite, enterSprite, pressedSprite, disableSprite;public GameObject normalObject, enterObject, pressedObject, disableObject;
  • 事件
     public ButtonEvent onClick;  //鼠标点击public ButtonEvent onEnter;  //鼠标移入public ButtonEvent onExit;   //鼠标移出public ButtonEvent onDown;   //鼠标按下public ButtonEvent onUp;     //鼠标抬起public ButtonEvent onDownStay; //按下持续
  • KGUI_Button Editor介绍

重点基于上述的属性进行在Editor赋值。

  1. 创建一个Editor类
 [CustomEditor(typeof(KGUI_Button))][CanEditMultipleObjects]public class KGUIButtonEditor : Editor{}

解析:
[CustomEditor(typeof(KGUI_Button))]告诉编辑器,编辑哪个类?[CanEditMultipleObjects] 用于使自定义编辑器支持多对象编辑的属性。 然后创建的类集成Editor类。

注意:同时才可以在KGUI_Button类中(需要写编辑器的类)添加[ExecuteInEditMode]特性,这个特性的意思是在编辑器下,也会执行Awake()、Start()、Enable()、Update()。

  1. 初始化一些数据
    类创建完毕后,就可以初始化KGUI_Button的属性了,在对Inspector属性窗口中进行控件的绘制。
     //需要绘制的属性对象public SerializedProperty onEnter;  //鼠标移入public SerializedProperty onExit;   //鼠标移出public SerializedProperty onDown;   //鼠标按下public SerializedProperty onUp;     //鼠标抬起//一些对象public SerializedProperty spriteRenderer;public SerializedProperty image;public SerializedProperty normalSprite, enterSprite, pressedSprite, disableSprite;public SerializedProperty normalObject, enterObject, pressedObject, disableObject;//进行编辑器编辑的类对象private KGUI_Button button;

当大家看到上述的一些SerializedProperty定义会觉得非常奇怪,为什么要这么写,这是序列化属性,什么意思呢,就是我们需要序列化出KGUI_Button类中的属性对象,从而能在后面进行绘制出来。

在OnEnable()函数中编写,对定义的SerializedProperty字段进行赋值。

     private void OnEnable(){button = serializedObject.targetObject as KGUI_Button;onClick = serializedObject.FindProperty("onClick");onEnter = serializedObject.FindProperty("onEnter");onExit = serializedObject.FindProperty("onExit");onDown = serializedObject.FindProperty("onDown");onUp = serializedObject.FindProperty("onUp");onDownStay = serializedObject.FindProperty("onDownStay");buttonType = serializedObject.FindProperty("buttonType");spriteRenderer = serializedObject.FindProperty("spriteRenderer");image = serializedObject.FindProperty("image");normalSprite = serializedObject.FindProperty("normalSprite");enterSprite = serializedObject.FindProperty("enterSprite");pressedSprite = serializedObject.FindProperty("pressedSprite");disableSprite = serializedObject.FindProperty("disableSprite");normalObject = serializedObject.FindProperty("normalObject");enterObject = serializedObject.FindProperty("enterObject");pressedObject = serializedObject.FindProperty("pressedObject");disableObject = serializedObject.FindProperty("disableObject");}

解析:
serializedObject.FindProperty(“onClick”);以这个为例,它的意思是查找序列化对象下的onClick属性/字段。
上述的工作,初始化常用的属性也就基本完毕了。下面在OnInspectorGUI()进行绘制。
3. 具体实现
1)首先要实现选择不同的枚举,绘制出来的信息是不一样的,那么我们可以如下所示这么写:

这样子我们就可以根据选择不同的枚举信息进行绘制不同的窗口了。

2)绘制继承UnityEngine.Object属性的两种方式

同时我们在上述的图片中,看到很多EditorGUILayout.PropertyField(),这个就是绘制出你编辑器的属性字段,它不用管你是什么类型,只要你对某个属性进行序列化查找赋值,那么它都可以在Inspector窗口中绘制出来,当然一般像int、bool、枚举、vector等都不用这个,因为Unity提供了这些基本的控件。

同时只要是你集成UnityEngine.Object的属性,比如GameObject、Component、Transform等那么你可以不用这么编写,用我们在【Windows窗口开发】下的EditorGUILayout.ObjectField()方法也是可以的,这样的话,你就不需要定义SerializedProperty字段以及在OnEnable初始化了,不过在编写Inspector窗口时,还是推荐用EditorGUILayout.PropertyField()

3)绘制非UnityEngine.Object属性的方式

当然如果是非UnityEngine.Object属性,比如Unity的事件(UnityEvent)事件,那么你就不能EditorGUILayout.ObjectField(),因为这是绘制不出来的,你只能采用EditorGUILayout.PropertyField()。这点本人在写Windows窗口时,尝试过。

四、Hierarchy右键菜单开发

在有些情况,我们需要在Hierarchy邮右键时,也想出现我们自定义的菜单项,应该怎么做呢?

     [MenuItem("MagiCloud/KGUI/Control/KGUI_Toggle(开关)")] //在菜单栏显示[MenuItem("GameObject/MagiCloud/KGUI/KGUI_Toggle(开关)", validate = false, priority = 10)]private static void CreateKGUI_Toggle(){//获取到选中的物体Transform[] selectedObject = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.ExcludePrefab);Transform parent = GetSeleteTransform();var ui = Resources.Load<GameObject>("UI/Toggle");CreateController(parent, ui);}/// <summary>/// 获取到选中的Trnsform/// </summary>/// <returns></returns>static Transform GetSeleteTransform(){Transform[] selectedObject = Selection.GetTransforms(SelectionMode.TopLevel | SelectionMode.ExcludePrefab);return selectedObject.Length == 0 ? null : selectedObject[0];}

[MenuItem(“GameObject/KGUI/KGUI_Toggle(开关)”, validate = false, priority = 10)]重要是这行代码,在静态方法中,添加如上述所示,那么在Hierarchy窗口中,右键就可以出现这个菜单项,则上述代码的实现就是获取到选中的物体,在这个物体下生成控件等功能。

五、结束语

好了,这篇博客就介绍在这里了,后续的博客我将详细介绍我的KGUI一些控件,里面会涉及到很多的UGUI一些知识、一些设计思路、射线、屏幕坐标计算等等。

大家如果看了,有疑问可以关注微信公众号(Hua灬清),有问题在这里回复即可,博客统一不回复,也不要发邮件、加QQ。

UnityEditor-Windows编辑器与Inspector编辑器相关推荐

  1. R语言使用edit函数在Rsudio中生成数据编辑器(在windows中生成编辑器)、在编辑器中输出需要的数据生成最终的dataframe

    R语言使用edit函数在Rsudio中生成数据编辑器(在windows中生成编辑器).在编辑器中输出需要的数据生成最终的dataframe 目录

  2. 用java实现的文本编辑器可以媲美windows自带的编辑器吗?(功能全,超详细)

    介绍 1.菜单栏(文本,编辑,格式,关于) 2.文本子菜单及其功能 3.编辑子菜单及其功能 4.格式子菜单及其功能 5.关于 实现功能 1. 编辑器可以打开,保存,另存为,关闭文件. 2. 编辑器可以 ...

  3. Markdown编辑器和富文本编辑器的区别

    目录 引言 Markdown编辑器和富文本编辑器的区别 Markdown的说明 引言 如果想要得到不带任何格式的文字,那么就不需要复杂的工具,windows的自带的文本编辑器就可以. 但是在日常的生活 ...

  4. 基于Unity编辑器开发技能编辑器(一)

    编辑器拓展介绍 常见的Unity编辑器拓展使用主要是创建自定义的窗体进行使用,包括剧情编辑器,动画编辑器,技能编辑器等等.最常使用的就是 EditorGUI,EditorGUILayout,GUI. ...

  5. ARM加速更迭,国产“芯”替代迎来新战机,123BOM编辑器(BOM123编辑器)是硬件工程师整理BOM的好帮手,嵌入式硬件工程师未来可期

    123BOM编辑器(BOM123编辑器)是硬件工程师整理BOM的好帮手 BOM123编辑器(www.BOM123.com)是硬件工程师整理BOM的好帮手 (www.123BOM.com) 近年来ARM ...

  6. 轻量级html编辑器推荐,HTML编辑器有哪些,HTML编辑器推荐

    对于很多初学者来说,一款好用的 HTML 编辑器是相当重要的.编辑器在前期可以帮我们快速的熟悉 HTML 代码,更快的上手,当我们能独立用记事本完成一个网页的制作,那么就说明我们学会 HTML 了. ...

  7. ue编辑器漏洞_7. 编辑器漏洞整理

    1.常见的编辑器 常见的有Ewebeditor,fckeditor,ckeditor,kindeditor等等.这里有份编辑器漏洞手册: 2.Ewebeditor编辑器 Ewebeditor是基于浏览 ...

  8. 所见即所得编辑器_Froala所见即所得编辑器

    所见即所得编辑器 Froala WYSIWYG Editor Froala Editor is a lightweight WYSIWYG rich text editor with a nice f ...

  9. CSDN 富文本编辑器和 Markdown 编辑器使用 Word 支持的 LaTx 语法公式

    CSDN 富文本编辑器和 Markdown 编辑器使用 Word 支持的 LaTx 语法公式 1.LaTx语法代码表示 公式显示 X=(x11x12-x21x22-⋮⋮⋱)\mathbf{X}=\le ...

  10. TatukGIS Developer Kernel ToolkitWinform GIS编辑器,C#地理信息编辑器,.NET地理信息编辑器...

    TatukGIS Developer Kernel (DK)是一款全面的GIS控件(SDK),用于自定义开发单独的.嵌入式的和CS模式的应用程序,完全依照OGC标准,支持将近3000种预定义坐标系统, ...

最新文章

  1. [转载]注册机破解法的原理以及应对方法
  2. Dubbo-Admin 功能展示与实操解析
  3. createrepo常用参数
  4. 寻路基本工具类定义 AIDefine.cpp
  5. 光纤模块与光纤收发器的区别
  6. 蓝桥杯基础模块06_1:定时器计数器
  7. 图片优化_网站里的图片应该如何优化
  8. C++新特性探究(十七):chrono计時器
  9. Visual C# 2008+SQL Server 2005 数据库与网络开发--9.2.1 XML文档
  10. Mocha BSM产品亮点——如何去干扰事件
  11. sqlserver Split 开放写法有兴趣的学习一下
  12. 二级python和office哪个难_对于操作office来说,python能与vbs相比吗?谁强谁弱呢?...
  13. android下拉菜单_如何调整和重新排列Android的快速设置下拉菜单
  14. 路由器 OSPF 路由汇总配置
  15. 计算机不联网会有ip地址吗,IP地址到底有什么用,为什么每次上网IP会不同?
  16. Gerrit代码审计系统实战-Gerrit 2.15.14版本快速搭建
  17. 苏州计算机云联盟协会,【缤FUN社团】计算机协会
  18. U-Mail邮件服务器软件的四大优势
  19. 为技术解开枷锁的那个人走了
  20. Scrapy爬取猫眼《复仇者联盟4终局之战》影评

热门文章

  1. CLRC66301国产替代,国产首颗全协议NFC芯片,可兼容A卡,B卡,F卡,15693卡,KK量级出货。
  2. 射频识别技术漫谈(16)——Mifare UltraLight
  3. 畅捷通(chanjet)T1各版本
  4. Android电量优化全解析
  5. Pix4D生成正射影像和DSM详细教程(可下载)
  6. 类的说明补充,对象的学习
  7. 某热门单击手游lua解密.md
  8. ACM竞赛入门分析与学习资源总结
  9. Springboot 项目打包 Compilation failure: Compilation failure:
  10. 十天学会php 零基础,十天学会php:第一天