汉化效果
利用Attribute可以自定义一些属性,实现汉化:
用法示例
TitleTest.cs
using UnityEngine;
using UnityEngine.Events;
[System.Serializable]
public class Item {
[Title("名称")]
public string name;
[EnumName("类型")]
public Type type = Type.A;
public enum Type {
[EnumName("消耗品")]
A,
[EnumName("任务道具")]
B
}
}
/// <summary>
/// 标题属性测试
/// <para>ZhangYu 2018-06-21</para>
/// </summary>
public class TitleTest : MonoBehaviour {
[Title("等级")]
public int level;
[Title("姓名")]
public string name;
[EnumName("武器")]
public Weapon weapon;
[EnumName("铠甲")]
public Armor armor;
[Title("道具列表", "yellow")]
public Item[] items;
[Title("死亡回调方法", "#FF0000")]
public UnityEvent onDead;
[Title("复活回调方法", "#00FF00")]
public UnityEvent onRevive;
public enum Weapon {
[EnumName("蛇矛")]
A,
[EnumName("胜宗刀")]
B,
[EnumName("青缸剑")]
C,
[EnumName("李广弓")]
D
}
public enum Armor {
[EnumName("钢甲")]
One,
[EnumName("火焰甲")]
Two,
[EnumName("青龙甲")]
Three,
[EnumName("藤甲")]
Four
}
void Start () {
}
}
Attribute脚本
TitleAttribute.cs
using UnityEngine;
#if UNITY_EDITOR
using System;
using UnityEditor;
using System.Reflection;
using System.Text.RegularExpressions;
#endif
/// <summary>
/// 标题属性
/// <para>ZhangYu 2018-06-21</para>
/// </summary>
#if UNITY_EDITOR
[AttributeUsage(AttributeTargets.Field)]
#endif
public class TitleAttribute : PropertyAttribute {
/// <summary> 标题名称 </summary>
public string title;
/// <summary> 标题颜色 </summary>
public string htmlColor;
/// <summary> 在属性上方添加一个标题 </summary>
/// <param name="title">标题名称</param>
/// <param name="htmlColor">标题颜色</param>
public TitleAttribute(string title, string htmlColor = "#FFFFFF") {
this.title = title;
this.htmlColor = htmlColor;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(TitleAttribute))]
public class TitleAttributeDrawer : DecoratorDrawer {
// 文本样式
private GUIStyle style = new GUIStyle();
public override void OnGUI(Rect position) {
// 获取Attribute
TitleAttribute attr = (TitleAttribute)attribute;
// 转换颜色
Color color = htmlToColor(attr.htmlColor);
// 重绘GUI
position = EditorGUI.IndentedRect(position);
style.normal.textColor = color;
GUI.Label(position, attr.title, style);
}
public override float GetHeight() {
return base.GetHeight() - 4;
}
/// <summary> Html颜色转换为Color </summary>
/// <param name="hex"></param>
/// <returns></returns>
private Color htmlToColor(string hex) {
// 默认黑色
if (string.IsNullOrEmpty(hex)) return Color.black;
// 转换颜色
hex = hex.ToLower();
if (hex.IndexOf("#") == 0 && hex.Length == 7) {
int r = Convert.ToInt32(hex.Substring(1, 2), 16);
int g = Convert.ToInt32(hex.Substring(3, 2), 16);
int b = Convert.ToInt32(hex.Substring(5, 2), 16);
return new Color(r / 255f, g / 255f, b / 255f);
} else if (hex == "red") {
return Color.red;
} else if (hex == "green") {
return Color.green;
} else if (hex == "blue") {
return Color.blue;
} else if (hex == "yellow") {
return Color.yellow;
} else if (hex == "black") {
return Color.black;
} else if (hex == "white") {
return Color.white;
} else if (hex == "cyan") {
return Color.cyan;
} else if (hex == "gray") {
return Color.gray;
} else if (hex == "grey") {
return Color.grey;
} else if (hex == "magenta") {
return Color.magenta;
} else {
return Color.black;
}
}
}
#endif
/// <summary>
/// 设置枚举名称
/// <para>ZhangYu 2018-06-21</para>
/// </summary>
#if UNITY_EDITOR
[AttributeUsage(AttributeTargets.Field)]
#endif
public class EnumNameAttribute : PropertyAttribute {
/// <summary> 枚举名称 </summary>
public string name;
public EnumNameAttribute(string name) {
this.name = name;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(EnumNameAttribute))]
public class EnumNameDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
// 替换属性名称
EnumNameAttribute rename = (EnumNameAttribute)attribute;
label.text = rename.name;
// 重绘GUI
bool isElement = Regex.IsMatch(property.displayName, "Element \\d+");
if (isElement) label.text = property.displayName;
if (property.propertyType == SerializedPropertyType.Enum) {
drawEnum(position, property, label);
} else {
EditorGUI.PropertyField(position, property, label, true);
}
}
// 绘制枚举类型
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];
while (type.IsArray) type = type.GetElementType();
// 获取枚举所对应的名称
for (int i = 0; i < names.Length; i++) {
FieldInfo info = type.GetField(names[i]);
EnumNameAttribute[] atts = (EnumNameAttribute[])info.GetCustomAttributes(typeof(EnumNameAttribute), false);
values[i] = atts.Length == 0 ? names[i] : atts[0].name;
}
// 重绘GUI
int index = EditorGUI.Popup(position, label.text, property.enumValueIndex, values);
if (EditorGUI.EndChangeCheck() && index != -1) property.enumValueIndex = index;
}
}
#endif
PS1:感谢雨松momo和他的文章:《Unity3D研究院之Inspector面板枚举的别名与排序(八十九)》
PS2:转载请注明原文地址:https://segmentfault.com/a/11...