Customized UI interface inspector panel (Editor) and custom parameter display effects in the inspector panel (PropertyDrawer)

Usually after we build an interface, we will add an interface script to the interface. Usually it is an ordinary MonoBehaviour.

At this time, the parameters defined in the script can be displayed in the inspector panel through the public or attribute [SerializeField].

But sometimes we may want to add a button to the panel, and then click the button in editor mode to execute a method in the script. In this case, we need to customize the panel.

The code is as follows:

Common interface script:

There are two lists in this script: templateDatas stores the instance data, and templates stores the created instance objects.

and some initialization methods

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 东/西部概况界面
/// </summary>
public class GeneralSituation : MonoBehaviour
{
    /// <summary>
    /// 示例物体
    /// </summary>
    private Template template;
    /// <summary>
    /// 显示区域
    /// </summary>
    private Transform content;
    
    /// <summary>
    /// 实例列表
    /// </summary>
    private List<Template> templates = new List<Template>();

    /// <summary>
    /// 实例数据列表
    /// </summary>
    [SerializeField]
    private List<TemplateData> templateDatas = new List<TemplateData>();

    /// <summary>
    /// 初始化实例
    /// </summary>
    public void InitTemplates()
    {
        
    }
    
    /// <summary>
    /// 初始化
    /// </summary>
    public void Init()
    {
        if(template == null)
        {
            template = this.transform.Find("Template").GetComponent<Template>();
        }
        if(content == null)
        {
            content = this.transform.Find("显示列表/Viewport/Content");
        }
    }
}

Template and TemplateData data scripts:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// 概况界面实例
/// </summary>
public class Template : MonoBehaviour
{
    /// <summary>
    /// 标签
    /// </summary>
    [SerializeField]
    private Text title;
    /// <summary>
    /// 值
    /// </summary>
    [SerializeField]
    private Text value;
    /// <summary>
    /// 字体颜色
    /// </summary>
    [SerializeField]
    private Color color;

    /// <summary>
    /// 设置标签内容
    /// </summary>
    /// <param name="title"></param>
    public void SetTitle(string title)
    {
        this.title.text = title;
        this.title.color = color;
    }

    /// <summary>
    /// 设置值
    /// </summary>
    /// <param name="value"></param>
    public void SetValue(string value)
    {
        this.value.text = value;
        this.value.color = color;
    }

    /// <summary>
    /// 设置颜色
    /// </summary>
    /// <param name="color"></param>
    public void SetColor(Color color)
    {
        this.color = color;
        this.title.color = color;
        this.value.color = color;
    }

    /// <summary>
    /// 获取标签内容
    /// </summary>
    /// <returns></returns>
    public string GetTitle()
    {
        return this.title.text;
    }
}

/// <summary>
/// 实例数据
/// </summary>
[Serializable]
public class TemplateData
{
    [SerializeField]
    public string title;
    [SerializeField]
    public string value;
    [SerializeField]
    public Color color;

    public TemplateData(string title, string value, Color color)
    {
        this.title = title;
        this.value = value;
        this.color = color;
    }
}

Interface editor script:

This script inherits Editor, adds the feature [CustomEditor(typeof(specific interface class))], and then implements the OnInspectorGUI() method to customize the inspector display panel. The rendering is as follows

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

/// <summary>
/// 东/西部概况界面编辑器
/// </summary>
[CustomEditor(typeof(GeneralSituation))]
public class GeneralSituationEditor : Editor
{
    GeneralSituation ui;
    GUILayoutOption[] options = new GUILayoutOption[] { GUILayout.Width(100f) };
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        ui = (GeneralSituation)this.target;

        ui.Init();

        GUILayout.BeginVertical();
//若设置了参数的显示效果,此处可注释掉
        for (int i = 0; i < ui.templateDatas.Count; i++)
        {
            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("标题:", new GUILayoutOption[] { GUILayout.Width(30f) });
            ui.templateDatas[i].title = EditorGUILayout.TextField(ui.templateDatas[i].title, options);
            EditorGUILayout.LabelField("值:", new GUILayoutOption[] { GUILayout.Width(30f) });
            ui.templateDatas[i].value = EditorGUILayout.TextField(ui.templateDatas[i].value, options);
            EditorGUILayout.LabelField("颜色:", new GUILayoutOption[] { GUILayout.Width(30f) });
            ui.templateDatas[i].color = EditorGUILayout.ColorField(ui.templateDatas[i].color, options);

            if (GUILayout.Button("-", new GUILayoutOption[] { GUILayout.Width(20f) }))
            {
                ui.templateDatas.Remove(ui.templateDatas[i]);
            }
            GUILayout.EndHorizontal();
        }

        if (GUILayout.Button("+", new GUILayoutOption[] { GUILayout.Width(20f) }))
        {
            ui.templateDatas.Add(new TemplateData("", "", Color.white));
        }

//可注释
        if (GUILayout.Button("确定", new GUILayoutOption[] { GUILayout.Width(100f) }))
        {
            ui.InitTemplates();
        }

        GUILayout.EndVertical();
    }
}

Rendering:

 To modify the parameters displayed in the inspector panel, you need to create a new script that inherits PropertyDrawer, then add the attribute [CustomPropertyDrawer(typeof(parameter class name))], and then implement the OnGUI() method. The example is as follows

TemplateDataDrawer:

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

/// <summary>
/// 实例数据编辑器
/// </summary>
[CustomPropertyDrawer(typeof(TemplateData))]
public class TemplateDataDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginProperty(position, label, property);
        //FocusType.Passive 使用Tab键切换时不会被选中,FocusType.Keyboard 使用Tab键切换时会被选中
        position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
        //不让indentLevel层级影响到同一行的绘制,因为PropertyDrawer在很多地方都有可能被用到,可能出现嵌套使用
        var indent = EditorGUI.indentLevel;
        EditorGUI.indentLevel = 0;
        //定义各数据显示区域位置与大小
        var titleRect = new Rect(position.x, position.y,100, position.height);
        var valueRect = new Rect(position.x + 105, position.y, 50, position.height);
        var colorRect = new Rect(position.x + 160, position.y, 50, position.height);
        //设置参数对应位置与大小
        EditorGUI.PropertyField(titleRect, property.FindPropertyRelative("title"), GUIContent.none);
        EditorGUI.PropertyField(valueRect, property.FindPropertyRelative("value"), GUIContent.none);
        EditorGUI.PropertyField(colorRect, property.FindPropertyRelative("color"), GUIContent.none);
        EditorGUI.indentLevel = indent;
        EditorGUI.EndProperty();
    }
}

The effect is as shown in the figure:

The combination of the two can achieve customized effects of the inspector panel, and of course they can also be used separately.

Guess you like

Origin blog.csdn.net/qq_42720695/article/details/126282838