Unity editor editor plug-in production basis: 2. Script component inspector Edtor GUILayout advanced panel function extension

a note

  1. The script must inherit the Editor, so the script cannot be bound to an object in the scene
  2. Use [CustomEditor(typeof(common script component name))] before Class to associate the current script with the bound common script class name in the scene. The reason for this design is that scripts that inherit MonoBehiver run under runtime. If you want to run under editor conditions, you need to extend it through Editor binding
  3. Editor can be placed under the Editor directory, which will not be exported along with the game package. But sometimes when the editor's support for the Editor class is faulty, you can put it in the normal directory to solve the problem.
  4. The ui drawing code needs to be placed in the public override void OnInspectorGUI() cycle, and DrawDefaultInspector() needs to be called inside; used to update the ui

Two Inspector implementation of advanced ui components

2.1 Libraries that need to be imported

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;

2.2 UI drawing function

The ui extension in the Inspector should be written in the OnInspectorGUI cycle and call DrawDefaultInspector to update the information

 public override void OnInspectorGUI()
 {
    
    
        // 刷新
        DrawDefaultInspector();
        ....draw ui....
 }

2.3 UI component drawing

// slider、scrollbar的值
    public float sliderValue;
    // toggle的值
    public bool toggleButtonValue;
    // tab的index值
    public int tabIndex = 0;
    // text / passfiald的值
    public string text;
    // inspector ui刷新
    public override void OnInspectorGUI()
    {
    
    
        // 刷新
        DrawDefaultInspector();
        // 获取目标脚本对象
        MapCreator myScript = (MapCreator)target;
        // ================== ui控件 ===========
        // 直接在这里创建组件,会自动累加到MapCreator脚本组件的inspector面板的下方。
        // 在组件参数中输入new Rect(0, 0, 300, 20)可以设置尺寸与位置
        // GUILayout 和 gui的区别是一个是自动布局一个是绝对布局
        // 创建默认尺寸按钮
        if (GUILayout.Button("创建对象"))
        {
    
    
            // 将目标脚本的方法绑定到按钮的事件
            myScript.BuildObject();
        }
        // layout的按钮
        GUILayout.Button("I am completely inside an Area");
        // 创建矩形提示盒
        GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue));
        //创建 水平滑竿
        sliderValue = GUILayout.HorizontalSlider(sliderValue, 0.0f, 10f);
        // 垂直滑竿
        sliderValue = GUILayout.VerticalSlider(sliderValue, 0.0f, 10f);
        // 水平滚动条 值;滑竿的长度;最小值;最大值
        sliderValue = GUILayout.HorizontalScrollbar(sliderValue, 5f, 0.0f, 10f);
        // 垂直滚动条
        sliderValue = GUILayout.VerticalScrollbar(sliderValue, 5f, 0.0f, 10f);
        // 密码框
        text = GUILayout.PasswordField(text, '*');
        // label
        GUILayout.Label("lable");
        // 只要按住就会重复发送true的按钮
        GUILayout.RepeatButton("holdon button");
        // switch 开关
        toggleButtonValue = GUILayout.Toggle(toggleButtonValue, "Toggle Button"))
        // tab/单选按钮组/switch开关
        string[] buttonNameList = {
    
     "1", "2", "3", "4", "5", "6" };
        switch (GUILayout.Toolbar(tabIndex, buttonNameList))
        {
    
    
            case 1:
                // 使[]index为1的按钮处于按下的状态 
                tabIndex = 1;
                break;
            case 2:
                tabIndex = 2;
                break;
            default:
                break;
        }
    }

2.4 Component Layout

2.4.1 The difference between positioning layout and automatic layout
  1. The position of the components in the positioning layout is set by ourselves. Components in the same position will cover each other, and when clicked, all controls will be penetrated and set off at the same time.
  2. The automatic layout will automatically arrange the position, and arrange it behind the previous control according to the setting of the horizontal or vertical group
2.4.2 Realize automatic layout

Write controls using GUILayout
Determine the layout area and vertical/horizontal direction by calling begin and end methods

2.4.3 Realize positioning layout

Use GUI to write controls
or use GUILayout, and enter the Rect parameter: for example GUILayout.BeginGroup(new Rect(0, 0, Screen.width, Screen.height));

public override void OnInspectorGUI()
 {
    
    
        // 刷新
        DrawDefaultInspector();
        // // 绝对布局,会覆盖在其他组件之上,并且在同一位置会穿透点击,自动布局会自动排列在物体后或下方
        // GUILayout.BeginGroup(new Rect(0, 0, Screen.width, Screen.height));
        // // (0,0)是群组的左上角
        // // 创建框以便于知道群组在屏幕上的位置
        // GUI.Box(new Rect(0, 0, Screen.width, Screen.height), "Group is here");
        // GUILayout.Button(new Rect(20, 20, 30, 30), "Click me");
        // // 结束前面开始的群组。这很重要,请记住!
        // GUILayout.EndGroup();

        //相对布局//自动布局
        // GUILayout.BeginArea(new Rect(0, 0, 300, 300));
        // GUILayout.Button("I am completely inside an Area");
        // GUILayout.Button("I am not inside an Area");
        // GUILayout.EndArea();

        // 带有垂直/水平方案的布局   由于使用Rect所以自动布局也变成了绝对定位
        GUILayout.BeginArea(new Rect(0, Screen.height - 330, 300, 300));
        //开启垂直布局
        GUILayout.BeginVertical();
        // 嵌套第一个水平布局
        GUILayout.BeginHorizontal();
        GUILayout.Button("I am completely inside an Area");
        GUILayout.Button("I am not inside an Area");
        GUILayout.EndHorizontal();
        // 嵌套第二个水平布局
        GUILayout.BeginHorizontal();
        GUILayout.Button("I am completely inside an Area");
        GUILayout.Button("I am not inside an Area");
        GUILayout.EndHorizontal();
        GUILayout.EndVertical();
        GUILayout.EndArea();
        //设置面板高度
        GUILayout.Space(300);
    }

Three complete scripts

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
// 绑定目标脚本
[CustomEditor(typeof(TargetScriptName))]
public class MapCreatorEditor : Editor //必须继承Editor
{
    
    
    // slider、scrollbar的值
    public float sliderValue;
    // toggle的值
    public bool toggleButtonValue;
    // tab的index值
    public int tabIndex = 0;
    // text / passfiald的值
    public string text;
    // inspector ui刷新
    public override void OnInspectorGUI()
    {
    
    
        // 刷新
        DrawDefaultInspector();
        // 获取目标脚本对象
        MapCreator myScript = (MapCreator)target;
        // ================== ui控件
        // 直接在这里创建组件,会自动累加到MapCreator脚本组件的inspector面板的下方。
        // 在组件参数中输入new Rect(0, 0, 300, 20)可以设置尺寸与位置
        // 创建默认尺寸按钮
        if (GUILayout.Button("创建对象"))
        {
    
    
            // 将目标脚本的方法绑定到按钮的事件
            myScript.BuildObject();
        }
        // layout的按钮
        GUILayout.Button("I am completely inside an Area");
        // 创建矩形提示盒
        GUILayout.Box("Slider Value: " + Mathf.Round(sliderValue));
        //创建 水平滑竿
        sliderValue = GUILayout.HorizontalSlider(sliderValue, 0.0f, 10f);
        // 垂直滑竿
        sliderValue = GUILayout.VerticalSlider(sliderValue, 0.0f, 10f);
        // 水平滚动条 值;滑竿的长度;最小值;最大值
        sliderValue = GUILayout.HorizontalScrollbar(sliderValue, 5f, 0.0f, 10f);
        // 垂直滚动条
        sliderValue = GUILayout.VerticalScrollbar(sliderValue, 5f, 0.0f, 10f);
        // 密码框
        text = GUILayout.PasswordField(text, '*');
        // label
        GUILayout.Label("lable");
        // 只要按住就会重复发送true的按钮
        GUILayout.RepeatButton("holdon button");
        // switch 开关
        toggleButtonValue = GUILayout.Toggle(toggleButtonValue, "Toggle Button"))
        // tab/单选按钮组/switch开关
        string[] buttonNameList = {
    
     "1", "2", "3", "4", "5", "6" };
        switch (GUILayout.Toolbar(tabIndex, buttonNameList))
        {
    
    
            case 1:
                // 使[]index为1的按钮处于按下的状态 
                tabIndex = 1;
                break;
            case 2:
                tabIndex = 2;
                break;
            default:
                break;
        }
  		// ======================布局相关=========================
        // GUILayout 和 gui的区别是一个是自动布局一个是绝对布局
        // // 绝对布局,会覆盖在其他组件之上,并且在同一位置会穿透点击
        // GUILayout.BeginGroup(new Rect(0, 0, Screen.width, Screen.height));
        // // (0,0)是群组的左上角
        // // 创建框以便于知道群组在屏幕上的位置
        // GUI.Box(new Rect(0, 0, Screen.width, Screen.height), "Group is here");
        // GUILayout.Button(new Rect(20, 20, 30, 30), "Click me");
        // // 结束前面开始的群组。这很重要,请记住!
        // GUILayout.EndGroup();

        //相对布局//自动布局
        // GUILayout.BeginArea(new Rect(0, 0, 300, 300));
        // GUILayout.Button("I am completely inside an Area");
        // GUILayout.Button("I am not inside an Area");
        // GUILayout.EndArea();

        // 带有垂直/水平方案的布局
        GUILayout.BeginArea(new Rect(0, Screen.height - 330, 300, 300));
        //开启垂直布局
        GUILayout.BeginVertical();
        // 嵌套第一个水平布局
        GUILayout.BeginHorizontal();
        // 窗口菜单模式,使用window字符 将内置一个窗口用于显示ui组件
        GUILayout.BeginHorizontal("My Tools", "window", new[] {
    
     GUILayout.Height(400), GUILayout.Width(100) });
        GUILayout.Button("I am completely inside an Area");
        GUILayout.Button("I am not inside an Area");
        GUILayout.EndHorizontal();
        // 嵌套第二个水平布局
        GUILayout.BeginHorizontal();
        //收尾
        GUILayout.EndHorizontal();
        GUILayout.EndVertical();
        GUILayout.EndArea();
        //设置面板高度
        GUILayout.Space(300);
    }
}

Guess you like

Origin blog.csdn.net/lengyoumo/article/details/113122328