在Unity中简化绘图枚举标志



在本出版物中,我将尝试简要地讨论C#中的枚举类型,将其用作标志以及如何在Unity检查器中简化其绘制。

什么是枚举?


枚举是C#中的重要类型,由一组常量组成。 关键字enum用于声明它。 每个枚举器都有一个整数值。 第一个默认值为0 ,随后的默认值加1

enum Color { Red, // 0 Green, // 1 Blue // 2 } 

您可以使用初始值设定项来覆盖值。

 enum Color { Red = 1, Green = 2, Blue = 3 } 

每种枚举类型都有一个基本类型,它可以是除char外的任何整数类型(默认为int )。 也可以明确指定。

 enum Color : byte { Red = 1, Green = 2, Blue = 3 } 

标志


有时有必要赋予实体许多属性。 您可以声明多个字段或创建一个列表,但是有时一个列表就足够了。 要将枚举用作标志,请添加特殊属性System.FlagsAttribute 。 这就需要对值进行显式初始化,并将每个值都提高为幂。

 [System.FlagsAttribute] enum Color : byte { None = 0, Red = 1, // 2 ^ 0 Green = 2, // 2 ^ 1 Blue = 4 // 2 ^ 2 } 

使用按位运算,可以合并枚举元素,并使用HasFlag(Enum)方法检查实例中是否存在位字段。

 var color = Color.Red | Color.Green | Color.Blue; var hasFlag = color.HasFlag(Color.Red | Color.Green); // True 

您也可以使用AND按位运算执行检查。

 var aColor = Color.Red | Color.Green; var bColor = Color.Green | Color.Blue; //     var contains = (aColor & bColor) == bColor; // False //     var overlaps = (aColor & bColor) != 0; // True 

Unity中的转移


例如,使用下面的代码。

 using UnityEngine; public enum Color { Red, Green, Blue } public class Example : MonoBehaviour { public Color Color; } 

内置的Unity工具可让您以下拉列表的形式显示枚举。



不幸的是,编辑器无法以标志的形式自动绘制枚举。 为此,需要重新定义检查器,这总是很不方便。 但是,您可以使用技巧,并在全局范围内重新定义工程图枚举。 首先,修改示例。

 using System; using UnityEngine; [Flags] public enum Color { Red = 1, Green = 2, Blue = 4 } public class Example : MonoBehaviour { public Color Color; } 

接下来,您需要实现PropertyDrawer 。 如果serializable属性具有Flags属性,则将使用EditorGUI.MaskField方法进行绘制,否则将使用标准的EditorGUI.PropertyField方法。 还要注意,属性可以是数组的元素。 下面的代码应放在名为Editor的文件夹中。

 [CustomPropertyDrawer(typeof(Enum), true)] public sealed class EnumPropertyDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { using (new EditorGUI.PropertyScope(position, label, property)) { if (HasEnumFlagsAttribute()) { var intValue = EditorGUI.MaskField(position, label, property.intValue, property.enumDisplayNames); if (property.intValue != intValue) { property.intValue = intValue; } } else { EditorGUI.PropertyField(position, property, label); } } bool HasEnumFlagsAttribute() { var fieldType = fieldInfo.FieldType; if (fieldType.IsArray) { var elementType = fieldType.GetElementType(); return elementType.IsDefined(typeof(FlagsAttribute), false); } return fieldType.IsDefined(typeof(FlagsAttribute), false); } } } 

现在,该字段已正确显示在检查器中,适用于任何枚举类型。



除了某些枚举值外,编辑器还添加了两个:

  • -整数值为0 ;
  • 一切 -具有-1的整数。

相关连结


Source: https://habr.com/ru/post/zh-CN456852/


All Articles