首页 > 其他分享 >在检视器Inspector中通过自定义属性实现显示中文名称

在检视器Inspector中通过自定义属性实现显示中文名称

时间:2024-06-18 19:30:48浏览次数:22  
标签:检视 name 自定义 CustomLabelAttribute label Inspector property type string

在前人的基础上,整出来了一些完善一些的版本
首先,在\Scripts下创建一个类CustomLabelAttribute 

using System;
using UnityEngine;

#if UNITY_EDITOR
[AttributeUsage(AttributeTargets.Field)]
#endif

/// <summary>
/// 使字段在Inspector中显示自定义的名称。
/// </summary>
public class CustomLabelAttribute : PropertyAttribute
{
    public string name;
    /// <summary>
    /// 使字段在Inspector中显示自定义的名称。
    /// </summary>
    /// <param name="name">自定义名称</param>
    public CustomLabelAttribute(string name)
    {
        this.name= name;
    }
}

建立了一个自定义属性,具体用法为:
 

    [CustomLabel("自定义的名称")]
    private bool flag;

然后,我们在\Editor下面创建另一个类CustomLabelDrawer (具体绘制时执行用的类)

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using System.Reflection;
using System.Text.RegularExpressions;
#endif
using System;

#if UNITY_EDITOR
    /// <summary>
    /// 定义对带有 `CustomLabelAttribute` 特性的字段的面板内容的绘制行为。
    /// </summary>
[CustomPropertyDrawer(typeof(CustomLabelAttribute))]
public class CustomLabelDrawer : PropertyDrawer{
    private GUIContent _label = null;
    private bool reProperty = true;
    private Dictionary<string, string> customEnumNames = new Dictionary<string, string>();

该类继承PropertyDrawer,在 OnGUI 方法中进行绘制

  public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){

        
        reProperty = true;
        //判断是否为集合类型
        bool isElement = Regex.IsMatch(property.displayName, "Element \\d+");
        //判断是否为枚举类型
        bool isEnum = property != null && property.propertyType == SerializedPropertyType.Enum;
        if (_label == null)
        {
            GetPropertyHeight(property, label);
            string reName="";
            //绘制自定义的名称
            string name = (attribute as CustomLabelAttribute).name;
            //如果是集合,那么修改其中的前缀
            if (isElement)
            {
                //如果是枚举类型就返回“元素X”,否则返回这个元素的“name”
                //这里我不知道如何获取集合中的序号,始终会返回 0,只能等后续有人改进了
                if (isEnum) name = "元素" + property.enumValueIndex;
                else name = property.displayName;
            }
            _label = new GUIContent(name+ reName);
        }

        if (isEnum)//如果是枚举,单独绘制
        {
            DrawEnum(position, property, _label);
            reProperty = false;
        }



        if (reProperty) EditorGUI.PropertyField(position, property, _label, true);
    }

获取存在[CustomLabelAttribute(string)]中的名称并返回

如果存在一些折叠的变量(集合等)会导致布局错乱,所以我抄了一个大佬的作品来优化了一下布局的高度

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        float baseHeight = base.GetPropertyHeight(property, label);
        if (property.isExpanded)
        {
            if (property.propertyType == SerializedPropertyType.Generic)
            {
                return baseHeight + EditorGUIUtility.singleLineHeight * property.CountInProperty();
            }
        }
        return baseHeight;
    }
    //作者:MUXIGameStudio https://www.bilibili.com/read/cv9094952/

绘制枚举时有点麻烦,因此单独提取成一个方法

    private void DrawEnum(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginChangeCheck();
        Type type = fieldInfo.FieldType;
        string[] names = property.enumNames;
        string[] values = new string[names.Length];

        //这里是判断List<enum>以及其他集合类型时将type转为其中的具体类型
        while (!type.IsArray&&typeof(System.Collections.IEnumerable).IsAssignableFrom(type))
        {
            type = type.GenericTypeArguments[0];
        }

        //这里是判断enum[]时将type转为其中的具体类型
        while (type.IsArray)
        {
            type = type.GetElementType();
        }

        for (int i = 0; i < names.Length; ++i)
        {
            FieldInfo info = type.GetField(names[i]);
            var enumAttributes = (CustomLabelAttribute[])info.GetCustomAttributes(typeof(CustomLabelAttribute), false);
            values[i] = enumAttributes.Length == 0 ? names[i] : enumAttributes[0].name;//+" "+ i;

        }

        int index = EditorGUI.Popup(position, label.text, property.enumValueIndex, values);
        if (EditorGUI.EndChangeCheck() && index != -1)
        {
            property.enumValueIndex = index;
        }
    }

之前的代码是只能判断emum[],而不能判断List<enum>,让我挺恼火的,折腾了半天总算是解决了,因此发出来,希望以后如果有人也遇到这个问题时可以提供一点帮助。

标签:检视,name,自定义,CustomLabelAttribute,label,Inspector,property,type,string
From: https://blog.csdn.net/m0_69630773/article/details/139781003

相关文章

  • react 自定义鼠标右键点击事件
    功能:鼠标右键点击节点时,出现“复制”功能,点击其他部位,隐藏“复制”;鼠标右键事件的文案,始终在鼠标点击位置的右下方;点击复制,提示复制成功效果图:代码:const[showRight,setShowRight]=useState(false);constcontextMenu=useRef(null);const[clickX,setClickX]=us......
  • 【踩坑】.NET 8.0 自定义IExceptionHandler不生效
    中间件实现异常处理在ASP.NETCore里,我们可以使用中间件(Middleware)实现全局的异常处理。如内置的异常处理中间件UseExceptionHandlerapp.UseExceptionHandler(appError=>{appError.Run(asynccontext=>{context.Resp......
  • Qt 应用程序中自定义鼠标光标
    在Qt应用程序中,你可以自定义鼠标光标。你可以使用`QCursor`类来设置不同类型的鼠标光标,比如内置样式或者自定义的图片。以下是一些使用示例:使用内置光标样式Qt提供了一些内置的光标样式,你可以使用这些样式来改变光标的外观,例如箭头、手形、等待图标等等。1#include<QA......
  • 20、docker-自定义网络
    查看所有的docker网络 网络模式:·bridge桥接(docker默认、自己定义也使用桥接模式)·none  不配置网络·host和宿主机共享网络·container容器网络连通(用的少) ================================================================......
  • React中AntDesign upload组件 自定义请求将多个上传请求合并成一个并
    接口文档核心代码constImportPictureUpload=()=>{const[fileList,setFileList]=useState([])constonBeforeUpload=(file:any,fileList:any)=>{setFileList(fileList)returnfalse;}useEffect(()=>{if(......
  • 5 个 JavaScript 自定义的实用函数
    嘿!......
  • 【iOS】自定义cell及其复用机制
    文章目录cell的复用注册非注册两者的区别自定义cellcell的复用当用户滚动UITableView或UICollectionView时,只有少量可见的cell会被实际创建和显示。对于那些暂时不可见的cell,系统会将它们缓存起来以备将来复用。这就是所谓的cell复用机制。为什么需要......
  • 【JAVA开发笔记】实战演练,如何用EasyExcel导出表格,并且自定义合并单元格
    目录1.前言2.EasyExcel简介3.EasyExcel简单导出案例讲解3.1EasyExcel依赖引入3.2测试类创建3.3Excel导出实现4.EasyExcel合并单元案例讲解4.1实现自定义合并策略4.2 使用自定义合并策略5.总结1.前言项目上,需将一个列表数据导出Excel表格,并将指定列相同......
  • 机器视觉入门学习:YOLOV5自定义数据集部署、网络详解、损失函数(学习笔记)
     前言源码学习资源:YOLOV5预处理和后处理,源码详细分析-CSDN博客网络学习资源:YOLOv5网络详解_yolov5网络结构详解-CSDN博客YOLOv5-v6.0学习笔记_yolov5的置信度损失公式-CSDN博客 本文为个人学习,整合各路大佬的资料进行V5-6.0版本的网络分析,在开始学习之前最好先去学习YOL......
  • 前端使用 Konva 实现可视化设计器(15)- 自定义连接点、连接优化
    前面,本示例实现了折线连接线,简述了实现的思路和原理,也已知了一些缺陷。本章将处理一些缺陷的同时,实现支持连接点的自定义,一个节点可以定义多个连接点,最终可以满足类似图元接线的效果。请大家动动小手,给我一个免费的Star吧~大家如果发现了Bug,欢迎来提Issue哟~github源码g......