/******************************************************************************/ /* Project - MudBun Publisher - Long Bunny Labs http://LongBunnyLabs.com Author - Ming-Lun "Allen" Chou http://AllenChou.net */ /******************************************************************************/ #if UNITY_EDITOR using System; using UnityEngine; using UnityEditor; namespace MudBun { [CustomPropertyDrawer(typeof(ConditionalFieldAttribute))] public class ConditionalFieldAttributeDrawer : PropertyDrawer { public static string AsStringValue(SerializedProperty property) { switch (property.propertyType) { case SerializedPropertyType.String: return property.stringValue; case SerializedPropertyType.Character: case SerializedPropertyType.Integer: if (property.type == "char") return System.Convert.ToChar(property.intValue).ToString(); return property.intValue.ToString(); case SerializedPropertyType.ObjectReference: return property.objectReferenceValue != null ? property.objectReferenceValue.ToString() : "null"; case SerializedPropertyType.Boolean: return property.boolValue.ToString(); case SerializedPropertyType.Enum: return property.enumNames[property.enumValueIndex]; default: return string.Empty; } } private ConditionalFieldAttribute Attribute { get { return _attribute ?? (_attribute = attribute as ConditionalFieldAttribute); } } private string PropertyToCheck { get => Attribute != null ? _attribute.PropertyToCheck : null; } private object CompareValue { get => Attribute != null ? _attribute.CompareValue : null; } private object CompareValue2 { get => Attribute != null ? _attribute.CompareValue2 : null; } private object CompareValue3 { get => Attribute != null ? _attribute.CompareValue3 : null; } private object CompareValue4 { get => Attribute != null ? _attribute.CompareValue4 : null; } private object CompareValue5 { get => Attribute != null ? _attribute.CompareValue5 : null; } private object CompareValue6 { get => Attribute != null ? _attribute.CompareValue6 : null; } private ConditionalFieldAttribute _attribute; private bool ShouldShow(SerializedProperty property) { if (PropertyToCheck != null && !PropertyToCheck.Equals("")) { var conditionProperty = FindPropertyRelative(property, PropertyToCheck); if (conditionProperty != null) { var aCompVal = new object[] { CompareValue, CompareValue2, CompareValue3, CompareValue4, CompareValue5, CompareValue6, }; bool matched = false; foreach (object compVal in aCompVal) { if (compVal == null) continue; bool isBoolMatch = conditionProperty.propertyType == SerializedPropertyType.Boolean && conditionProperty.boolValue; string compareStringValue = compVal != null ? compVal.ToString().ToUpper() : "NULL"; if (isBoolMatch && compareStringValue == "FALSE") isBoolMatch = false; string conditionPropertyStringValue = AsStringValue(conditionProperty).ToUpper(); bool objectMatch = compareStringValue == conditionPropertyStringValue; if (!isBoolMatch && !objectMatch) continue; matched = true; break; } if (!matched) { return false; } } } return true; } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { return ShouldShow(property) ? EditorGUI.GetPropertyHeight(property) : 0.0f; } // TODO: Skip array fields public override void OnGUI(Rect position, SerializedProperty property, GUIContent content) { if (!ShouldShow(property)) return; if (!Attribute.Label.Equals("")) content.text = Attribute.Label; if (!Attribute.Tooltip.Equals("")) content.tooltip = Attribute.Tooltip; if (Attribute.ShowRange) { if (property.propertyType == SerializedPropertyType.Float) EditorGUI.Slider(position, property, Attribute.Min, Attribute.Max, content); else if (property.propertyType == SerializedPropertyType.Integer) EditorGUI.IntSlider(position, property, Convert.ToInt32(Attribute.Min), Convert.ToInt32(Attribute.Max), content); else EditorGUI.LabelField(position, content.text, "Use Range with float or int."); } else { EditorGUI.PropertyField(position, property, content); } } private SerializedProperty FindPropertyRelative(SerializedProperty property, string toGet) { if (property.depth == 0) return property.serializedObject.FindProperty(toGet); var path = property.propertyPath.Replace(".Array.data[", "["); var elements = path.Split('.'); SerializedProperty parent = null; for (int i = 0; i < elements.Length - 1; i++) { var element = elements[i]; int index = -1; if (element.Contains("[")) { index = Convert.ToInt32(element.Substring(element.IndexOf("[", StringComparison.Ordinal)).Replace("[", "").Replace("]", "")); element = element.Substring(0, element.IndexOf("[", StringComparison.Ordinal)); } parent = i == 0 ? property.serializedObject.FindProperty(element) : parent.FindPropertyRelative(element); if (index >= 0) parent = parent.GetArrayElementAtIndex(index); } return parent.FindPropertyRelative(toGet); } } } #endif