Unity汉化字段重命名Inspector中字段属性时显示错位及其解决办法——Unity常见问题
标题Unity汉化字段重命名Inspector中字段属性时显示错位及其解决办法
众所周知,OnInspectorGUI()和OnGUI()是Unity的Editor和PropertyDrawer类里的相关函数,通过对该方法的重写,可以自定义对Inspector面板的绘制。于是乎,原本干净整洁的Unity Inspector开始越来越多的出现了中文。网上随便一搜,大街小巷的都是教程
如出一辙的重命名教程
不管教程怎么变,都是换汤不换药,就是指定自定义属性,然后重写OnInspectorGUI()或者OnGUI()修改字段的Label。但是默认情况下这种方法非常好使,不会出现怎么问题。
但是!,如果大家平时写代码的时候不拘泥与效果实现,在注重程序的可维护性时,一般都会建大量的底层类,而且存在大量组合关系的时候问题就出现了
当尝试序列化一个非Mono对象脚本时,视图出现了显示错误,高度不会自动更新。
通过阅读PropertyDrawer的源码发现了问题所在
public abstract class PropertyDrawer : GUIDrawer{internal PropertyAttribute m_Attribute;internal System.Reflection.FieldInfo m_FieldInfo;public PropertyAttribute attribute => this.m_Attribute;public System.Reflection.FieldInfo fieldInfo => this.m_FieldInfo;internal void OnGUISafe(Rect position, SerializedProperty property, GUIContent label){ScriptAttributeUtility.s_DrawerStack.Push(this);this.OnGUI(position, property, label);ScriptAttributeUtility.s_DrawerStack.Pop();}///
///Override this method to make your own IMGUI based GUI for the property.///
///Rectangle on the screen to use for the property GUI.///The SerializedProperty to make the custom GUI for.///The label of this property.public virtual void OnGUI(Rect position, SerializedProperty property, GUIContent label){EditorGUI.DefaultPropertyField(position, property, label);EditorGUI.LabelField(position, label, EditorGUIUtility.TempContent("No GUI Implemented"));}///
///Override this method to make your own UIElements based GUI for the property.///
///The SerializedProperty to make the custom GUI for.//The element containing the custom GUI.///public virtual VisualElement CreatePropertyGUI(SerializedProperty property) => (VisualElement) null;internal float GetPropertyHeightSafe(SerializedProperty property, GUIContent label){ScriptAttributeUtility.s_DrawerStack.Push(this);float propertyHeight = this.GetPropertyHeight(property, label);ScriptAttributeUtility.s_DrawerStack.Pop();return propertyHeight;}///
///Override this method to specify how tall the GUI for this field is in pixels.///
///The SerializedProperty to make the custom GUI for.///The label of this property.//The height in pixels.///public virtual float GetPropertyHeight(SerializedProperty property, GUIContent label) => 18f;internal bool CanCacheInspectorGUISafe(SerializedProperty property){ScriptAttributeUtility.s_DrawerStack.Push(this);bool flag = this.CanCacheInspectorGUI(property);ScriptAttributeUtility.s_DrawerStack.Pop();return flag;}///
///Override this method to determine whether the inspector GUI for your property can be cached.///
///The SerializedProperty to make the custom GUI for.//Whether the drawer's UI can be cached.///public virtual bool CanCacheInspectorGUI(SerializedProperty property) => true;}
}
一眼就能看出问题所在,百度的方法没有去重写GetPropertyHeight(SerializedProperty property, GUIContent label)方法,连方法都不重写,怎么让Editor知道怎么绘制你呢?
我们开始重写,首先调用基类的方法
float baseHeight = base.GetPropertyHeight(property,label);
然后发生问题大部分都是自定义类的序列化该序列化对象,通过阅读文档可知属于
SerializedPropertyType.Generic
然后发生问题大部分需要在Inspector中展开序列化对象时错位,阅读文档得知,通过SerializedProperty.isExpanded可以判断对象是否展开
得到代码:
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;
}
我们最后只需要在if内判断该字段展开后的高度即可!出于通用性的原因考虑,这里使用
EditorGUIUtility.singleLineHeight * property.CountInProperty()来得到高度。
其中EditorGUIUtility.singleLineHeight是Unity字段在Inspector中的通用高度,property.CountInProperty()是当前序列化对象的子字段数量。
最后附上优化后的完整代码,支出绝大部分字段的重命名以及颜色修改。
using System;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;namespace Game.Attribute
{#if UNITY_EDITOR[AttributeUsage(AttributeTargets.Field)]
#endifpublic class RenameAttribute : PropertyAttribute {/// 枚举名称 public readonly string Name = "";/// 文本颜色 public readonly string HtmlColor = "#ffffff";/// 重命名属性 /// 新名称public RenameAttribute(string name) {Name = name;}/// 重命名属性 /// 新名称/// 文本颜色 例如:"#FFFFFF" 或 "black"public RenameAttribute(string name,string Color) {Name = name;HtmlColor = OrColor;}public RenameAttribute(string name, Color htmlColor) {Name = name;HtmlColor = htmlColor.ToString();}}#if UNITY_EDITOR[CustomPropertyDrawer(typeof(RenameAttribute))]public class RenameDrawer : PropertyDrawer {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;}public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {using (new EditorGUI.PropertyScope(position, label, property)){RenameAttribute rename = (RenameAttribute)attribute;label.text = rename.Name;// 重绘GUIColor defaultColor = EditorStyles.label.normal.textColor;EditorStyles.label.normal.textColor = htmlToColor(rename.HtmlColor);bool isElement = Regex.IsMatch(property.displayName, "Element \\d+");if (isElement) if (base.attribute != rename) label.text = property.displayName; else label.text += property.displayName.Substring(8);if (property.propertyType == SerializedPropertyType.Enum) {DrawEnum(position, property, label);} else if(property.propertyType==SerializedPropertyType.Generic){EditorGUI.PropertyField(position,property, label,true);} else{EditorGUI.PropertyField(position, property, label);}EditorStyles.label.normal.textColor = defaultColor;}// 替换属性名称}// 绘制枚举类型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];Array.Copy(names, values, names.Length);while (type.IsArray) type = type.GetElementType();// 获取枚举所对应的RenameAttributefor (int i = 0; i < names.Length; i++) {FieldInfo info = type.GetField(names[i]);RenameAttribute[] atts = (RenameAttribute[])info.GetCustomAttributes(typeof(RenameAttribute), true);if (atts.Length != 0) values[i] = atts[0].Name;}// 重绘GUIint index = EditorGUI.Popup(position, label.text, property.enumValueIndex, values);if (EditorGUI.EndChangeCheck() && index != -1) property.enumValueIndex = index;}/// Html颜色转换为Color /// 字符串颜色/// 返回Unity的Color类public static Color htmlToColor(string hex) {hex = hex.ToLower(); if(!String.IsNullOrEmpty(hex)){ColorUtility.TryParseHtmlString(hex, out Color color);return color;}return new Color(0.705f, 0.705f, 0.705f);}}
#endif
Unity汉化字段重命名Inspector中字段属性时显示错位及其解决办法——Unity常见问题相关推荐
- mysql字段重命名_MySQL中使用SQL语句对字段进行重命名
MySQL中,如何使用SQL语句来对表中某一个字段进行重命名呢?我们将使用alter table 这一SQL语句. 重命名字段的语法为:alter table change . 现在我们来尝试把tes ...
- 关于虚拟机中安装Ubuntu时界面显示不全的解决办法
如果帮助到您,还请点个关注吧,hahaha 楼主因为某种特别原因,需要重新装Ubuntu16.04,可是在分区的界面却看不到下一步的按钮了,瞬间头皮发麻.网上说默认分区方式不会遇到这种问题,但是强迫症 ...
- html ol 序号不出来,html中ol标签不显示序号的解决办法
html ol 和 ul 区别之一就是 ol 标签下面的 li 标签会自动带上序号,而是 ul 下面的 li 标签不会.如果 ol li 标签没有序号,原因很简单, 就是你重置了 ol 标签的左内边距 ...
- AndroidStudio1.4 manifest 中注册Activity时的错误提示解决办法
问题截图如下: 解决办法截图如下: 1: File->setting->Editor->Language Injections到如下界面 2:双击右侧选中的Item进入编辑界面 3: ...
- JOOQ学习笔记:分页、排序、字段重命名的写法
环境 JOOQ: "3.9.6" java:1.8 springboot:1.5.10.RELEASE 前言 最近进小黑屋赶项目: 公司封装的分页方法,字段接收上,不能满足我,所以 ...
- Python之pandas:对dataframe数据的索引简介、应用大全(输出索引/重命名索引列/字段去重/设置复合索引/根据列名获取对应索引)、指定某字段为索引列等详细攻略
Python之pandas:对dataframe数据的输出索引.重命名索引列/字段去重/设置复合索引/根据列名获取对应索引.指定某字段为索引列等详细攻略 目录 对pandas中dataframe数据中 ...
- pandas使用rename函数重命名dataframe中数据列的名称、从而创建一个包含重复列名称的dataframe数据集
pandas使用rename函数重命名dataframe中数据列的名称.从而创建一个包含重复列名称的dataframe数据集 目录
- 批量重命名文件中的照片
通过下列代码,可实现批量重命名文件中的照片 代码如下: import os import string main_path = './photo_new' picturelist = os.listd ...
- Java 对象转Json,@JSONField对象字段重命名和顺序问题
一.引入maven依赖 <dependency><groupId>com.alibaba</groupId><artifactId>fastjson&l ...
- @hotmail.com 账户添加别名,重命名到@outlook.com 一系列问题,顺道附上个人解决方法
@hotmail.com 账户添加别名,重命名到@outlook.com 一系列问题,顺道附上个人解决方法 参考文章: (1)@hotmail.com 账户添加别名,重命名到@outlook.com ...
最新文章
- 二叉树查找python_二叉搜索树的python实现
- AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilityManager
- 成功解决Error: Cannot find module 'web3'
- agv matlab应用,简单介绍一下agv调度控制系统常见的软件应用
- [Socket网络编程]一个封锁操作被对 WSACancelBlockingCall 的调用中断。
- application/json 四种常见的 POST 提交数据方式
- ListView自适应实现表格
- VB制作OCX控件的步骤
- 最简洁的PHP把PHP生成HTML代码
- Android图片加载那些事(一)-实现加载手机中的所有图片
- 微信小程序 git代码管理使用的详细步骤
- Linux内核网络UDP数据包发送(四)——Linux netdevice 子系统
- (初学者)关于C语言中退格键(\b)的初步了解
- 软考中级之系统集成项目管理工程师备考
- 剑指offer面试题2:实现单例模式
- 显卡性能比较 GPU common sense
- 龙格库塔公式法解微分方程组初值问题实例
- 唐太宗管理之道:收人,收心,收天下
- 浅谈分页插件PageHelper
- x265编码格式的avi视频播放只有声音,图像不出来的一种解决方式
热门文章
- SQL server2008 安装教程
- 主流HTML5游戏框架的分析和对比(Construct2、ImpactJS、CreateJS、Cocos2d-html5……)
- 中南民族大学计算机组成原理实验,中南民族大学计算机组成原理试题及答案剖析.docx...
- 在线教学质量评价系统java web_基于JavaWeb的教师教学质量评价系统
- Android--关闭某个指定activity,android开发游戏
- 【论文笔记】Evolving Deep Neural Networks.
- 《Android框架揭秘》——2.2节搭建Android平台编译环境
- 混响运行于CPU或者DSP时的部分指标对比
- 开放源代码不得不知的一些事情
- Python实例练手项目源码 - 关不掉的窗口