using UnityEngine; using UnityEditor; using System; namespace NaughtyAttributes.Editor { [CustomPropertyDrawer(typeof(LayerAttribute))] public class LayerPropertyDrawer : PropertyDrawerBase { private const string TypeWarningMessage = "{0} must be an int or a string"; protected override float GetPropertyHeight_Internal(SerializedProperty property, GUIContent label) { bool validPropertyType = property.propertyType == SerializedPropertyType.String || property.propertyType == SerializedPropertyType.Integer; return validPropertyType ? GetPropertyHeight(property) : GetPropertyHeight(property) + GetHelpBoxHeight(); } protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label) { EditorGUI.BeginProperty(rect, label, property); switch (property.propertyType) { case SerializedPropertyType.String: DrawPropertyForString(rect, property, label, GetLayers()); break; case SerializedPropertyType.Integer: DrawPropertyForInt(rect, property, label, GetLayers()); break; default: string message = string.Format(TypeWarningMessage, property.name); DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning); break; } EditorGUI.EndProperty(); } private string[] GetLayers() { return UnityEditorInternal.InternalEditorUtility.layers; } private static void DrawPropertyForString(Rect rect, SerializedProperty property, GUIContent label, string[] layers) { int index = IndexOf(layers, property.stringValue); int newIndex = EditorGUI.Popup(rect, label.text, index, layers); string newLayer = layers[newIndex]; if (!property.stringValue.Equals(newLayer, StringComparison.Ordinal)) { property.stringValue = layers[newIndex]; } } private static void DrawPropertyForInt(Rect rect, SerializedProperty property, GUIContent label, string[] layers) { int index = 0; string layerName = LayerMask.LayerToName(property.intValue); for (int i = 0; i < layers.Length; i++) { if (layerName.Equals(layers[i], StringComparison.Ordinal)) { index = i; break; } } int newIndex = EditorGUI.Popup(rect, label.text, index, layers); string newLayerName = layers[newIndex]; int newLayerNumber = LayerMask.NameToLayer(newLayerName); if (property.intValue != newLayerNumber) { property.intValue = newLayerNumber; } } private static int IndexOf(string[] layers, string layer) { var index = Array.IndexOf(layers, layer); return Mathf.Clamp(index, 0, layers.Length - 1); } } }