unity editor 编辑器插件制作基础:二、脚本组件inspector Edtor GUILayout高级面板功能扩展

一 说明

  1. 脚本必须继承Editor,因此脚本无法绑定在场景中的某个物体
  2. 在Class前使用[CustomEditor(typeof(普通脚本组件名))],将当前脚本与场景中已经绑定的普通脚本类名相关联。这么设计的原因是继承了MonoBehiver的脚本是在runtime下运行的,如果想在editor条件下就运行则需要通过Editor绑定来扩展
  3. Editor可以放在Editor目录下,该目录不会随着游戏打包而输出。但有时编辑器对Editor类支持有故障时可以将其放在普通目录中解决问题。
  4. ui绘制代码需放在public override void OnInspectorGUI()周期中,并且需要在里面调用 DrawDefaultInspector();用于更新ui

二 Inspector高级ui组件的实现

2.1 需要引入的库

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

2.2 UI绘制函数

Inspector中的ui扩展应该写在OnInspectorGUI周期中,并调用DrawDefaultInspector来更新信息

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

2.3 UI组件绘制

// 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 组件布局

2.4.1 定位布局和自动布局的区别
  1. 定位布局的组件位置由我们自己设定,相同位置的组件会相互覆盖,点击时会穿透所有控件同时出发
  2. 自动布局会自动排列位置,按水平或垂直group的设定排列在上一个控件后面
2.4.2 实现自动布局

使用GUILayout编写控件
通过调用bengin、end方法确定布局区域和垂直/水平方向

2.4.3 实现定位布局

使用GUI编写控件
或使用GUILayout,并输入Rect参数:例如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);
    }

三 完整脚本

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);
    }
}

猜你喜欢

转载自blog.csdn.net/lengyoumo/article/details/113122328