当前位置:   article > 正文

Inspector面板扩展(EditorGUI、EditorGUILayout、GUI、GUILayout)

editorgui

Inspector面板扩展(EditorGUI、EditorGUILayout、GUI、GUILayout)

前言

最近,一个项目涉及到比较多的模块,每个模块又有不同的情况和动作,有公用的,也有特例。所以为了方便修改(直接在面板上选择)并且一目了然,我使用了编辑器,画出我自己需要的Inspector面板,显示我需要的信息。同时,为了以后查看,特地来做整理。

这些信息是根据脚本中声明的public可序列化变量而来的,要美观并实用的显示这些信息,让面板更具可操作性,我们就需要使用到EditorGUI、EditorGUILayout、GUI、GUILayout等来进行规划和布局。

系统简介

转载:

1、系统简介具体的介绍见:https://blog.csdn.net/qq992817263/article/details/79292426/

2、GUILayoutEditorGUILayout 控件整理见:https://blog.csdn.net/qq_38275140/article/details/84778344

3「Unity3D」(10)自定义属性面板Inspector详解   From:scottcgi

简介:

1、GUI系统

这是运用最广泛的GUI系统,所属命名空间UnityEngine,用其绘制的所有控件不带有自动布局效果,需要手动指定每个控件的绘制位置和大小,自适应性较弱,但开发自由度较高

注意:GUI系统可以在发布后使用,也可以在编辑器中使用。

2、GUILayout系统

带自动布局的GUI系统,所属命名空间UnityEngine,用其绘制的所有控件都带有自动布局效果,自适应性较强,但开发自由度较低

注意:GUILayout系统可以在发布后使用,也可以在编辑器中使用。

3、EditorGUI系统

适用于编辑器的GUI系统,所属命名空间UnityEditor,用其绘制的所有控件不带有布局效果,需要手动指定每个控件的绘制位置和大小,跟GUI系统的差别是其拥有部分编辑器专用控件,且其只能运行在编辑器内,自适应性较弱,但开发自由度较高

注意:EditorGUI系统不可以在发布后使用,只能在编辑器中使用。

4、EditorGUILayout系统

带自动布局的EditorGUI系统,所属命名空间UnityEditor,用其绘制的所有控件都带有自动布局效果,跟GUILayout系统的差别是其拥有部分编辑器专用控件,且其只能运行在编辑器内,自适应性较强,但开发自由度较低

注意:EditorGUILayout系统不可以在发布后使用,只能在编辑器中使用。

以上四个GUI系统可以混用,EditorGUIEditorGUILayout系统中的控件多是带Field,可见其用意主要是用来展示字段的值,GUI系统由于不带布局,所以在编辑器开发中使用的较少,除非有时候需要创建高自由度的界面时会首选他,GUILayout系统开发编辑器工具是使用得最多的。

Inspector面板扩展

一、基本结构认识:

  1. 首先在Unity中的Project下建一个文件夹,命名为Editor;
  2. 新建一个C#脚本,命名为Test1Editor,放在刚刚新建的Editor文件夹下(注:Editor脚本最好都放在名为Editor的文件夹下);
  3. 新建一个文件夹,命名为Scripts,用来存放脚本;
  4. 在Scripts文件夹下新建一个C#脚本,命名为Test1。

1、绘制原有属性

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. #if UNITY_EDITOR
  4. using UnityEditor;
  5. #endif
  6. using UnityEngine;
  7. //CustomEditor(typeof()) 用于关联要自定义的脚本
  8. //CanEditMultipleObjects 支持多物体同时编辑
  9. [CustomEditor(typeof(Test1)),CanEditMultipleObjects]
  10. public class Test1Editor : Editor {
  11. private void OnEnable()
  12. {
  13. }
  14. //重写OnInspectorGUI
  15. public override void OnInspectorGUI()
  16. {
  17. // 绘制Test1全部原有public属性
  18. base.DrawDefaultInspector();
  19. // 后面可以自定义扩展自己的功能
  20. }
  21. }

2、自定义绘制属性

(1)基本框架:

  1. public override void OnInspectorGUI()
  2. {
  3. serializedObject.Update();//开头,更新显示,可以不写
  4. /*中间,自定义绘制*/
  5. serializedObject.ApplyModifiedProperties();//结尾,应用修改,必须有,不然不能修改
  6. }

(2)可以选择性的绘制public属性对象:

方法一:

  1. 定义
  2. 声明,在Test1中寻找要绘制的对象属性
  3. 重写OnInspectorGUI,进行绘制

   

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. #if UNITY_EDITOR
  4. using UnityEditor;
  5. #endif
  6. using UnityEngine;
  7. [CustomEditor(typeof(Test1))]
  8. public class Test1Editor : Editor {
  9. //定义
  10. static SerializedProperty vector2;
  11. private void OnEnable()
  12. {
  13. //声明(查找对象属性)FindProperty
  14. vector2 = serializedObject.FindProperty("vector2");
  15. }
  16. public override void OnInspectorGUI()
  17. {
  18. //绘制
  19. EditorGUILayout.PropertyField(vector2);
  20. //查找对象属性的属性并赋值(FindPropertyRelative)
  21. vector2.FindPropertyRelative("x").floatValue = 10f;
  22. serializedObject.ApplyModifiedProperties();
  23. }
  24. }

小结: 

  1. 有两个接口用来查找已有的属性(Test1中的public属性变量),FindProperty和FindPropertyRelative。
  2. FindProperty:用来查找当前属性名对应的属性对象。
  3. FindPropertyRelative:查找属性对象的属性。

方法二:

直接定义Test1:Test1 test1 = target as Test1;

  1. #if UNITY_EDITOR
  2. using UnityEditor;
  3. #endif
  4. [CustomEditor(typeof(Test1))]
  5. public class Test1Editor : Editor
  6. {
  7. public override void OnInspectorGUI()
  8. {
  9. Test1 test1 = target as Test1;
  10. test1.vector2 = EditorGUILayout.Vector2Field("二维坐标",test1.vector2);
  11. serializedObject.ApplyModifiedProperties();
  12. }
  13. }

二、绘制所用控件介绍

(一)空格的几种写法

  1. GUILayout.Space(10);//空格,写法1(可以控制空格大小,数字越小,空格越小)
  2. EditorGUILayout.Space();//空格,写法2
  3. EditorGUILayout.Separator();//分隔符

(二)布局类

1、BeginFadeGroup:用来隐藏/显示在它包含的组中的内容。value则是显示内容的量,范围是0~1 。设置为0.5,就是显示50%;设置为0.85,就是显示85%。

  1. public override void OnInspectorGUI()
  2. {
  3. EditorGUILayout.BeginFadeGroup(0.5f);
  4. EditorGUILayout.LabelField("Inspector");
  5. EditorGUILayout.LabelField("Inspector");
  6. EditorGUILayout.LabelField("Inspector");
  7. EditorGUILayout.EndFadeGroup();
  8. serializedObject.ApplyModifiedProperties();
  9. }

    

2、BeginHorizontal:水平布局;EndHorizontal:结束水平布局;
             BeginVertical:垂直布局;EndVertical:结束垂直布局

  1. EditorGUILayout.BeginHorizontal();
  2. EditorGUILayout.LabelField("水平布局1");
  3. EditorGUILayout.LabelField("水平布局2");
  4. EditorGUILayout.EndHorizontal();
  5. EditorGUILayout.Space();
  6. EditorGUILayout.BeginVertical();
  7. EditorGUILayout.LabelField("垂直布局1");
  8. EditorGUILayout.LabelField("垂直布局2");
  9. EditorGUILayout.EndVertical();

  

若加上"box",就会有个布局框,即:

EditorGUILayout.BeginHorizontal("box");

EditorGUILayout.EndHorizontal();

效果如下:

3、BeginScrollView:开始滚动视图;EndScrollView:结束滚动视图

  1. test1.scrollView=EditorGUILayout.BeginScrollView(test1.scrollView, GUILayout.Width(Screen.width), GUILayout.Height(80));
  2. EditorGUILayout.LabelField("这是ScrollView");
  3. EditorGUILayout.LabelField("这是ScrollView");
  4. EditorGUILayout.LabelField("这是ScrollView");
  5. EditorGUILayout.LabelField("这是ScrollView");
  6. EditorGUILayout.LabelField("这是ScrollView");
  7. EditorGUILayout.LabelField("这是ScrollView");
  8. EditorGUILayout.EndScrollView();

   

(三)Field类

1.Text:文本

  • EditorGUILayout.TextField:只能写一行
  • EditorGUILayout.TextArea:能换行写多行
  • EditorGUILayout.DelayedTextField:延时,要回车之后才提交修改
  1. [CustomEditor(typeof(Test1)),CanEditMultipleObjects]
  2. public class Test1Editor : Editor
  3. {
  4. private string textfiled;
  5. private string textarea;
  6. static SerializedProperty DelayedTextField;
  7. private void OnEnable()
  8. {
  9. DelayedTextField = serializedObject.FindProperty("DelayedTextField");
  10. }
  11. public override void OnInspectorGUI()
  12. {
  13. Test1 test1 = target as Test1;
  14. //TextField
  15. test1.Textfield= EditorGUILayout.TextField("TextField",test1.Textfield);//写法一
  16. textfiled = EditorGUILayout.TextField("textfiled", textfiled);//写法二
  17. //空格
  18. EditorGUILayout.Space();
  19. //TextArea
  20. test1.Textarea = EditorGUILayout.TextArea(test1.Textarea);
  21. textarea = EditorGUILayout.TextArea(textarea);
  22. EditorGUILayout.Space();
  23. //DelayedTextField
  24. EditorGUILayout.DelayedTextField(DelayedTextField);
  25. serializedObject.ApplyModifiedProperties();
  26. }
  27. }

   

2、Password:密码字段

  1. //Passworld
  2. test1.Password = EditorGUILayout.PasswordField("密码:", test1.Password);

  

3、数字

  1. IntField:整数字段                                 5. DelayedIntField:整数,延迟输入框
  2. FloatField:浮点数字段                         6. DelayedFloatField:浮点数,延迟输入框
  3. DoubleField:双精度浮点型字段           7. DelayedDoubleField:双精度浮点数,延迟输入框
  4. LongField:长整型字段 

     注:延迟输入框,在按下回车键或将焦点从文本字段移开之后,才返回新值

  1. static SerializedProperty DelayedIntField;
  2. static SerializedProperty DelayedFloatField;
  3. static double DelayedDoubleField;
  4. private void OnEnable()
  5. {
  6. DelayedIntField = serializedObject.FindProperty("DelayedIntField");
  7. DelayedFloatField = serializedObject.FindProperty("DelayedFloatField");
  8. }
  9. public override void OnInspectorGUI()
  10. {
  11. Test1 test1 = target as Test1;
  12. test1.intfield = EditorGUILayout.IntField("IntField", test1.intfield);
  13. test1.floatfield = EditorGUILayout.FloatField("FloatField", test1.floatfield);
  14. test1.doublefield = EditorGUILayout.DoubleField("DoubleField", test1.doublefield);
  15. test1.longfield = EditorGUILayout.LongField("LongField", test1.longfield);
  16. EditorGUILayout.Space();
  17. EditorGUILayout.DelayedIntField(DelayedIntField);
  18. EditorGUILayout.DelayedFloatField(DelayedFloatField);
  19. EditorGUILayout.DelayedDoubleField("DelayedDoubleField", DelayedDoubleField);
  20. serializedObject.ApplyModifiedProperties();
  21. }

   

4、BoundsField:边界输入框

  1. public override void OnInspectorGUI()
  2. {
  3. Test1 test1 = target as Test1;
  4. test1.bounds = EditorGUILayout.BoundsField("BoundsField:", test1.bounds);
  5. serializedObject.ApplyModifiedProperties();
  6. }
  1. public class Test1 : MonoBehaviour
  2. {
  3. public Bounds bounds;
  4. }

   

5、RectField:矩形字段

test1.rect= EditorGUILayout.RectField("RectField",test1.rect );

   

6.ObjectField:物体字段

  1. public override void OnInspectorGUI()
  2. {
  3. Test1 test1 = target as Test1;
  4. test1.objectfield = EditorGUILayout.ObjectField("ObjectField", test1.objectfield, typeof(Object), true);
  5. serializedObject.ApplyModifiedProperties();
  6. }
  1. public class Test1 : MonoBehaviour
  2. {
  3. public Object objectfield;
  4. }

  

 7、ColorField:颜色

test1.color = EditorGUILayout.ColorField("Color", test1.color);
  1. public class Test1 : MonoBehaviour
  2. {
  3. public Color color = Color.red;
  4. }

   

8、CurveField:曲线

test1.curvefield = EditorGUILayout.CurveField("CurveField", test1.curvefield);
  1. public class Test1 : MonoBehaviour
  2. {
  3. public AnimationCurve curvefield = AnimationCurve.Linear(0, 0, 10, 10);
  4. }

  

9、向量字段

  • Vector2Field:二维向量
  • Vector3Field:三维向量
  • Vector4Field:四维向量
  1. vector2field = EditorGUILayout.Vector2Field("Vector2Field", vector2field);
  2. vector3field = EditorGUILayout.Vector3Field("Vector3Field", vector3field);
  3. vector4field = EditorGUILayout.Vector4Field("Vector4Field", vector4field);

  

10、LayerField:层字段

  1. //LayerField
  2. EditorGUILayout.LayerField("LayerField",0);

  

  11、TagField:标签字段

EditorGUILayout.TagField("Tag for Objects:","这是一个Tag");

  

(四)选择开关按钮

1、Toggle 与 ToggleLeft

  1. test1.b1 = EditorGUILayout.Toggle("b1", test1.b1);
  2. test1.b2 = EditorGUILayout.ToggleLeft("b2", test1.b2);
  1. public class Test1 : MonoBehaviour
  2. {
  3. public bool b1, b2;
  4. }

  

2、BeginToggleGroup:开始开关组;EndToggleGroup:结束开关组

  1. //开始开关组
  2. test1.b3 = EditorGUILayout.BeginToggleGroup("ToggleGroup", test1.b3);
  3. test1.pos[0] = EditorGUILayout.Toggle("x", test1.pos[0]);
  4. test1.pos[1] = EditorGUILayout.Toggle("y", test1.pos[1]);
  5. test1.pos[2] = EditorGUILayout.Toggle("z", test1.pos[2]);
  6. //结束开关组
  7. EditorGUILayout.EndToggleGroup();
  1. public class Test1 : MonoBehaviour
  2. {
  3. public bool b3;
  4. public bool[] pos = new bool[3] { false, false, false };
  5. }

  

(五)Slider:滑动条

  • Slider:滑动条
  • IntSlider:整数滑动条
  • MinMaxSlider: 最小最大滑动条
  1. //滑动条
  2. test1.sliderValue = EditorGUILayout.Slider("Slider", test1.sliderValue, 0, 1);
  3. //整数滑动条
  4. test1.intSliderValue = EditorGUILayout.IntSlider("IntSlider", test1.intSliderValue, 0, 10);
  5. //最大最小滑动条
  6. EditorGUILayout.MinMaxSlider("MinMaxSlider", ref test1.minSliderValue, ref test1.maxSliderValue, 0, 10);
  1. public class Test1 : MonoBehaviour
  2. {
  3. public float sliderValue;
  4. public int intSliderValue;
  5. public float minSliderValue, maxSliderValue;
  6. }

   

(六)下拉列表

  •  Popup:标准弹出选择菜单
  • IntPopup:整数弹出选择菜单
  • EnumPopup:(单选)枚举弹出选择菜单
  • EnumMaskPopup:(多选)枚举弹出选择菜单
  • EnumMaskField:(多选)枚举弹出选择菜单
  • MaskField:(多选)数组弹出选择菜单
  • DropdownButton:(单选)下拉菜单
  1. #if UNITY_EDITOR
  2. using UnityEditor;
  3. #endif
  4. using UnityEngine;
  5. [CustomEditor(typeof(Test1)), CanEditMultipleObjects]//自定义预览窗
  6. public class Test1Editor : Editor {
  7. //声明
  8. int popupIndex;
  9. string[] popupArry = { "a", "b", "c" };
  10. static SerializedProperty choose1;
  11. private int maskField;
  12. private string DropdownButtonName= "DropdownButton";
  13. //定义
  14. private void OnEnable()
  15. {
  16. choose1 = serializedObject.FindProperty("choose1");
  17. }
  18. //规划面板
  19. public override void OnInspectorGUI()
  20. {
  21. Test1 test1 = target as Test1;
  22. //Popup
  23. EditorGUILayout.Popup("Popup", popupIndex, popupArry);
  24. //IntPopup
  25. test1.intPopup= EditorGUILayout.IntPopup("IntPopup",test1.intPopup, new string[] { "1", "2", "3" },new int[]{4,5,6});
  26. EditorGUILayout.PropertyField(choose1);//下拉列表
  27. //EnumPopup
  28. test1.choose2 = (Choose)EditorGUILayout.EnumPopup("EnumPopup", test1.choose2);
  29. //EnumMaskPopup
  30. test1.choose3 = (Choose)EditorGUILayout.EnumMaskPopup("EnumMaskPopup", test1.choose3);
  31. //EnumMaskField
  32. test1.choose4 = (Choose)EditorGUILayout.EnumMaskField("EnumMaskField", test1.choose4);
  33. //maskField
  34. maskField = EditorGUILayout.MaskField("MaskField", maskField, new string[] { "1", "2" });
  35. EditorGUILayout.Space();
  36. //DropdownButton
  37. if (EditorGUILayout.DropdownButton(new GUIContent(DropdownButtonName), FocusType.Keyboard))
  38. {
  39. string[] alls = new string[4] { "A", "B", "C", "D" };
  40. GenericMenu _menu = new GenericMenu();
  41. foreach (string item in alls)
  42. {
  43. if (string.IsNullOrEmpty(item))
  44. {
  45. continue;
  46. }
  47. //添加菜单
  48. _menu.AddItem(new GUIContent(item), DropdownButtonName.Equals(item), OnValueSelected, item);
  49. }
  50. //显示菜单
  51. _menu.ShowAsContext();
  52. }
  53. serializedObject.ApplyModifiedProperties();
  54. }
  55. void OnValueSelected(object value)
  56. {
  57. DropdownButtonName = value.ToString();
  58. switch (DropdownButtonName)
  59. {
  60. case "A":
  61. Debug.Log("A");
  62. break;
  63. case "B":
  64. Debug.Log("B");
  65. break;
  66. case "C":
  67. Debug.Log("C");
  68. break;
  69. case "D":
  70. Debug.Log("D");
  71. break;
  72. }
  73. }
  74. }
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. public enum Choose
  6. {
  7. choose1, choose2, choose3, choose4
  8. }
  9. public class Test1 : MonoBehaviour {
  10. public int intPopup;
  11. public Choose choose1 = Choose.choose1;
  12. public Choose choose2 = Choose.choose2;
  13. public Choose choose3;
  14. public Choose choose4;
  15. }

  

(七)数组

  1. #if UNITY_EDITOR
  2. using UnityEditor;
  3. #endif
  4. using UnityEngine;
  5. [CustomEditor(typeof(Test1)), CanEditMultipleObjects]//自定义预览窗
  6. public class Test1Editor : Editor {
  7. static SerializedProperty arry1,arry2;
  8. private void OnEnable()
  9. {
  10. arry1 = serializedObject.FindProperty("arry1");
  11. arry2 = serializedObject.FindProperty("arry2");
  12. }
  13. public override void OnInspectorGUI()
  14. {
  15. // 缩进一级【不然数组会顶格(左边),与上面的对不齐】
  16. EditorGUI.indentLevel++;
  17. EditorGUILayout.PropertyField(arry1, true);//要写true,不然打不开数组
  18. EditorGUILayout.PropertyField(arry2, true);
  19. serializedObject.ApplyModifiedProperties();
  20. }
  21. }
  1. public class Test1 : MonoBehaviour
  2. {
  3. public int[] arry1;
  4. public string[] arry2;
  5. }

  

(八)Foldout:折叠框

  1. using UnityEditor.AnimatedValues;
  2. #if UNITY_EDITOR
  3. using UnityEditor;
  4. #endif
  5. public class Test1Editor : Editor {
  6. private bool foldout;
  7. private AnimBool fadeGroup;
  8. private void OnEnable()
  9. {
  10. fadeGroup = new AnimBool(false);
  11. // 注册动画监听
  12. fadeGroup.valueChanged.AddListener(Repaint);
  13. }
  14. private void OnDisable()
  15. {
  16. // 移除动画监听
  17. fadeGroup.valueChanged.RemoveListener(Repaint);
  18. }
  19. public override void OnInspectorGUI()
  20. {
  21. foldout = EditorGUILayout.Foldout(foldout, "FoldOut");
  22. if (foldout)
  23. {
  24. EditorGUILayout.LabelField("这是一个折叠框");
  25. EditorGUI.indentLevel++;
  26. EditorGUILayout.LabelField("这是一个折叠框");
  27. EditorGUI.indentLevel--;
  28. }
  29. fadeGroup.target = EditorGUILayout.Foldout(fadeGroup.target, "BeginFadeGroup", true);
  30. if (EditorGUILayout.BeginFadeGroup(this.fadeGroup.faded))
  31. {
  32. EditorGUILayout.BoundsField("BoundsField", new Bounds());
  33. }
  34. // 动画
  35. EditorGUILayout.EndFadeGroup();
  36. serializedObject.ApplyModifiedProperties();
  37. }
  38. }

  

(九)HelpBox:帮助框

  1. public class Test1Editor : Editor {
  2. public override void OnInspectorGUI()
  3. {
  4. EditorGUILayout.HelpBox("这个没有属性", MessageType.None);
  5. EditorGUILayout.HelpBox("这是个错误", MessageType.Error);
  6. EditorGUILayout.HelpBox("这是个提示", MessageType.Info);
  7. EditorGUILayout.HelpBox("这是个警告", MessageType.Warning);
  8. serializedObject.ApplyModifiedProperties();
  9. }
  10. }

   

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号