Unity editor extension (2) - the use of GUI controls

Use of GUI controls

1. Rendering

insert image description here

Two, create a window

First of all, we first use the MenuItem introduced in the first section to create the window

  public class LearnWindow : EditorWindow
    {
    
    
        [MenuItem("Learn/Open LearnWindow %q")]
        public static void OpenWindow()
        {
    
    
            LearnWindow window = UnityEditor.EditorWindow.GetWindow<LearnWindow>();
        }
    }   

create window

Third, use the control to draw the window

Next we introduce some controls to draw the window

No input control

GUILayout.Label Label

GUILayout.Label("Label",EditorStyles.boldLabel);

The effect is as follows
insert image description here

input control

GUILayout series

GUILayout.TextField single line text
GUILayout.TextArea multi-line text
        private string textFieldVal;
        private string textAreaVal;
        private void OnGUI()
        {
    
                                    
            //TextField输入框(最多只能输入一行,不管高度多高)
            textFieldVal = GUILayout.TextField(textFieldVal);
            //TextArea输入框(可以输入多行)
            textAreaVal = GUILayout.TextArea(textAreaVal,GUILayout.Height(50));
         }            

The effect is as follows, the upper one is TextField, the lower one is TextArea
insert image description here

EditorGUILayout series

The above GUILayout is drawn as a pure input box, and we generally need to add a title to the input box as a reminder. At this time, you need to use the EditorGUILayout series of controls;

EditorGUILayout.IntField() input integer
EditorGUILayout.FloatField() Input floating point number
EditorGUILayout.TextField() Enter a single line of text
EditorGUILayout.TextArea() Input multiple lines of text
        private int editorLabelInt;
        private float editorLabelFloat;
        private string editorLabelText;
        private string editorLabelArea;
        private void OnGUI()
        {
    
               
            //EditorGUILayout(既可以显示标题,又可以承接输入内容)
            editorLabelInt = EditorGUILayout.IntField("输入int:",editorLabelInt);
            editorLabelFloat = EditorGUILayout.FloatField("输入float:",editorLabelFloat);
            editorLabelText = EditorGUILayout.TextField("输入string",editorLabelText);
            editorLabelArea = EditorGUILayout.TextArea("输入多行文本",GUILayout.Height(50));
        }            

The effect is as follows, it feels better than GUILayout
insert image description here

EditorGUILayout.Vector3Field() input vector
EditorGUILayout.ColorField() input color
EditorGUILayout.CurveField() input curve
        private Vector3 editorLabelVct3;
        private Color editorLabelColor;
        private AnimationCurve editorLabelCurve = new AnimationCurve(new Keyframe[]
        {
    
    
            new Keyframe(0,0),
            new Keyframe(1,1),
        });
        
        private void OnGUI()
        {
    
                        
            editorLabelVct3 = EditorGUILayout.Vector3Field("输入Vector3",editorLabelVct3);
            // editorLabelVct2 = EditorGUILayout.Vector3Field("输入Vector3",editorLabelVct2);
            // editorLabelVct4 = EditorGUILayout.Vector3Field("输入Vector3",editorLabelVct4);
            
            editorLabelColor = EditorGUILayout.ColorField("输入颜色",editorLabelColor);
            editorLabelCurve = EditorGUILayout.CurveField("输入Curve曲线",editorLabelCurve);

The effect is as follows
insert image description here

button

           //按钮
            if (GUILayout.Button("按钮"))
            {
    
    
                Debug.Log($"{
      
      GetType()} 按下按钮");
            }

The renderings are as follows
insert image description here

button with picture

		//除了传入文本之外,我们还可以传入GUIContent。
		//而GUIContent可以携带 图片+文本信息。我们可以用这个来创建带图片的按钮
		public static bool Button(GUIContent content, params GUILayoutOption[] options)      

Next, we encapsulate two methods for quickly building GUIContent

       //代码动态创建一张图片
        public static Texture2D CreateTex(Color color,int size)
        {
    
    
            Texture2D tex = new Texture2D(size,size);
            for (int i = 0; i < size; i++)
            {
    
    
                for (int j = 0; j < size; j++)
                {
    
    
                    tex.SetPixel(i,j,color);
                }
            }
            tex.Apply();
            return tex;
        }
        //创建 图片+文本 的GUIContent
        public static GUIContent CreateImgTextContent(string text,Color color,int size = 16)
        {
    
    
            GUIContent guiContent = new GUIContent(text,CreateTex(color,size));
            return guiContent;
        }

actual use

	GUILayout.Button(EditorUtil.CreateImgTextContent(" test",Color.blue,16));

Effect
insert image description here

  • After encapsulating the method, it is very convenient to add pictures or colors before the text, which can be used to make some distinctions. And in fact, what is created is GUIContent, which can be passed into buttons or other components

slider

GUILayout.HorizontalSlider() Ordinary slider
EditorGUILayout.IntSlider() integer slider
EditorGUILayout.Slider() floating point slider
        private float sliderVal;
        private int editorSliderInt;
        private float editorSliderFloat;
        
        private void OnGUI()
        {
    
               
            //滑动条
            sliderVal = GUILayout.HorizontalSlider(sliderVal, 0, 5);
            editorSliderInt = EditorGUILayout.IntSlider("Int滑动条", editorSliderInt,0,5);
            editorSliderFloat = EditorGUILayout.Slider("Float滑动条", editorSliderFloat,0,5);
        }

The renderings are as follows
insert image description here

switch

		private bool isToggle;
       
        private void OnGUI()
        {
    
    
                    //Toggle开关
            isToggle = GUILayout.Toggle(isToggle,"Toggle开关");
		}	

The renderings are as follows
insert image description here

drop down box

EditorGUILayout.EnumPopup() enumerates the drop-down box
EditorGUILayout.Popup() Default drop-down box
EditorGUILayout.IntPopup() Integer drop-down box
        public EditorEnum curEditorEnum;
        private int curIntPopupIndex;
        private int curPopupIndex;
        private void OnGUI()
        {
    
    
            //枚举值下拉框
            curEditorEnum = (EditorEnum) EditorGUILayout.EnumPopup("选择枚举值",curEditorEnum);
            
            curPopupIndex = EditorGUILayout.Popup("默认下拉框", curPopupIndex,new[] {
    
    "One", "Two", "Three"});
            
            //整型下拉框较之上面的默认下拉框多了指定序号的功能,由int[]数组定义。其他没多大区别          
            curIntPopupIndex = EditorGUILayout.IntPopup("整型下拉框", curIntPopupIndex,new[] {
    
    "One", "Two", "Three"},new[]{
    
    4,5,6});        	
        }             

The renderings are as follows
insert image description here

prompt box

EditorGUILayout.HelpBox() prompt box
            //helpBox
            EditorGUILayout.HelpBox($"helpBox:{
      
      MessageType.None}", MessageType.None);
            EditorGUILayout.HelpBox($"helpBox:{
      
      MessageType.Info}", MessageType.Info);
            EditorGUILayout.HelpBox($"helpBox:{
      
      MessageType.Warning}", MessageType.Warning);
            EditorGUILayout.HelpBox($"helpBox:{
      
      MessageType.Error}", MessageType.Error);

The prompt box is relatively simple, see the effect picture for details
insert image description here

popup interaction box

EditorUtility.DisplayDialog
        if (EditorUtility.DisplayDialog("标题", "内容", "确定", "取消"))
        {
    
    
            //在这里处理 点击确定按钮
        }

The renderings are as follows
Please add a picture description

EditorUtility.DisplayDialogComplex()

EditorUtility.DisplayDialog can only write OK button events, you can use this when you need more click events. Next on the code

        int select = EditorUtility.DisplayDialogComplex("标题", "内容", "确定", "取消","其他");
        Debug.Log($"click select:{
      
      select}");
        switch (select)
        {
    
    
            case 0:
                //在这里处理 点击确定按钮
                break;
            case 1:
                //在这里处理 点击取消按钮
                break;
            case 2:
                //在这里处理 点击其他按钮
                break;
        }

The renderings are as follows
Please add a picture description

pop-up prompt box

ShowNotification()

Sometimes we don't need the player to click OK one more time, but just give a simple prompt, such as 'saved successfully'. This is how we can use ShowNotification(); This method is a method of the EditorWindow window class, which can be used in our window class.

ShowNotification(new GUIContent("保存成功"));

The effect picture is as follows
insert image description here
Hey, it’s easy to use!

folding function

EditorGUILayout.Foldout() folding box

The folding function is a very practical function, but it is very simple to use. Next on the code

        private bool isFold;
        private void OnGUI()
        {
    
    
            //折叠功能
            isFold = EditorGUILayout.Foldout(isFold,"折叠列表");
            if (isFold)
            {
    
    
                GUILayout.Button("按钮1");
                GUILayout.Button("按钮2");
            }        	 
        }               

The effect diagram is as follows, and the bottom is the unfolded state. Click to collapse
insert image description here

radio button group

GUILayout.Toolbar() radio toolbar
GUILayout.SelectionGrid() Single selection toolbar (can control how many are displayed in one line)
		
		//Toolbar系列
        private string[] ToolBarTitles = new[] {
    
     "Menu1","Menu2","Menu3"};
        private int curToolBarIndex = 0;
        
        //Grid系列,较之上面的多了个指定一行几个按钮的功能
        private string[] GridBarTitles = new[] {
    
     "Grid1","Grid2","Grid3","Grid4"};
        private int curGridBarIndex = 0;
        private void OnGUI()
        {
    
    
            //Toolbar
            curToolBarIndex = GUILayout.Toolbar(curToolBarIndex,ToolBarTitles);

            EditorGUILayout.Space();
            EditorGUILayout.Space();            

            //Grid, 这里指定一行显示2个
            curGridBarIndex = GUILayout.SelectionGrid(curGridBarIndex, GridBarTitles, 2);
            
            if (GUI.changed)
            {
    
    
                Debug.Log($"{
      
      GetType()} curIndex:{
      
      curToolBarIndex} curGridBarIndex:{
      
      curGridBarIndex}");
            }
        }		

The effect picture is as follows, above is Toolbar, below is SelectionGrid
insert image description here

layout/group

GUILayout.BeginHorizontal() horizontal layout

The default layout in the GUI is a vertical layout, and a horizontal layout can be used to wrap controls. The controls in the layout will be arranged horizontally

            GUILayout.BeginHorizontal();
            GUILayout.Button("按钮1");
            GUILayout.Button("按钮2");
            GUILayout.EndHorizontal();

The renderings are as follows
insert image description here

GUILayout.BeginVertical() vertical layout
            GUILayout.BeginVertical();
            GUILayout.Button("按钮1");
            GUILayout.Button("按钮2");
            GUILayout.EndVertical();

The renderings are as follows
insert image description here

GUILayout.BeginArea controls the drawing area

Controlling the drawing area is also a more practical function. You can control which area to draw, and control the new starting point.

            float width = 300;
            float height = 300;
            GUILayout.BeginArea(new Rect(0,0,width,height));
            // GUI.Box(new Rect(0,0,width,height),"");
            GUILayout.BeginVertical();
            
            //在这里绘制实际内容 
            
            GUILayout.EndVertical();
            GUILayout.EndArea();

The effect picture is as follows, if it is empty, nothing can be seen. Generally, when drawing BeginArea, we use a Box box, so that there is a background, and it is better to see where the area is. Untie the
insert image description here
comment // GUI.Box(new Rect(0,0,width,height), ""); , you can see how big the actual area is.
insert image description here
The drawing area GUILayout.BeginArea() here needs to fill in a Rect() rectangle. It feels like the width and height are fixed. If you want the width to change with the change of the window, is there a way? Yes, use position.
After inheriting EditorWindow, there is a position variable. In fact, position is a rectangle Rect.
We can get four components:
position.x: window X starting point;
position.y: window Y starting point;
position.width: window width;
position.height: window height;

Modify the code, the area can be adaptive

            float offsetX = 10;
            float offsetY = 10;
            Rect rect = new Rect(offsetX,offsetX,position.width - 2 * offsetX,position.height - 2 * offsetY);
            
            GUILayout.BeginArea(rect);
            GUI.Box(rect,"");
            GUILayout.BeginVertical();
            
            //在这里绘制实际内容 
            
            GUILayout.EndVertical();
            GUILayout.EndArea();

You can see that the drawing area automatically becomes larger and smaller with the window
insert image description here

GUILayout.BeginScrollView() Add scroll bar

It is also common if there is a lot of content to be drawn that exceeds the visible window. Then you need to add scroll bars.

	 	private Vector2 scrollViewPos;
    
        private void OnGUI()
        {
    
    
            float width = 200;
            float height = 300;
            
            Rect rect = new Rect(0,0,width,height);
            
            GUILayout.BeginArea(rect);
            GUI.Box(rect,"");
            scrollViewPos = GUILayout.BeginScrollView(scrollViewPos,false,true,GUILayout.Height(height));
            GUILayout.BeginVertical();

            //在这里绘制实际内容 
            for (int i = 0; i < 50; i++)
            {
    
    
                GUILayout.Button($"按钮{
      
      i}");
                GUILayout.Space(5);
            }
            
            
            GUILayout.EndVertical();
            GUILayout.EndScrollView();
            GUILayout.EndArea();             	
		}             	

The renderings are as follows
insert image description here
Alright, this is the end of this introduction, and I will continue to supplement after mastering new practical knowledge!

Guess you like

Origin blog.csdn.net/aaa27987/article/details/119762469