public override bool CanDrawProperty(SerializedProperty property) { HideIfAttribute hideIfAttribute = PropertyUtility.GetAttribute <HideIfAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo conditionField = ReflectionUtility.GetField(target, hideIfAttribute.ConditionName); if (conditionField != null && conditionField.FieldType == typeof(bool)) { return(!(bool)conditionField.GetValue(target)); } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, hideIfAttribute.ConditionName); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { return(!(bool)conditionMethod.Invoke(target, null)); } string warning = hideIfAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, target); return(true); }
private object GetMaxValue(SerializedProperty property, ProgressBarAttribute progressBarAttribute) { if (string.IsNullOrEmpty(progressBarAttribute.MaxValueName)) { return(progressBarAttribute.MaxValue); } else { object target = PropertyUtility.GetTargetObjectWithProperty(property); FieldInfo valuesFieldInfo = ReflectionUtility.GetField(target, progressBarAttribute.MaxValueName); if (valuesFieldInfo != null) { return(valuesFieldInfo.GetValue(target)); } PropertyInfo valuesPropertyInfo = ReflectionUtility.GetProperty(target, progressBarAttribute.MaxValueName); if (valuesPropertyInfo != null) { return(valuesPropertyInfo.GetValue(target)); } MethodInfo methodValuesInfo = ReflectionUtility.GetMethod(target, progressBarAttribute.MaxValueName); if (methodValuesInfo != null && (methodValuesInfo.ReturnType == typeof(float) || methodValuesInfo.ReturnType == typeof(int)) && methodValuesInfo.GetParameters().Length == 0) { return(methodValuesInfo.Invoke(target, null)); } return(null); } }
public static void CallOnValueChangedCallbacks(SerializedProperty property) { OnValueChangedAttribute[] onValueChangedAttributes = GetAttributes <OnValueChangedAttribute>(property); if (onValueChangedAttributes.Length == 0) { return; } object target = GetTargetObjectWithProperty(property); property.serializedObject.ApplyModifiedProperties(); // We must apply modifications so that the new value is updated in the serialized object foreach (var onValueChangedAttribute in onValueChangedAttributes) { MethodInfo callbackMethod = ReflectionUtility.GetMethod(target, onValueChangedAttribute.CallbackName); if (callbackMethod != null && callbackMethod.ReturnType == typeof(void) && callbackMethod.GetParameters().Length == 0) { callbackMethod.Invoke(target, new object[] { }); } else { string warning = string.Format( "{0} can invoke only methods with 'void' return type and 0 parameters", onValueChangedAttribute.GetType().Name); Debug.LogWarning(warning, property.serializedObject.targetObject); } } }
public override bool CanDrawProperty(SerializedProperty property) { ShowIfAttribute showIfAttribute = PropertyUtility.GetAttribute <ShowIfAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo conditionField = ReflectionUtility.GetField(target, showIfAttribute.ConditionName); if (conditionField != null && conditionField.FieldType == typeof(bool)) { return((bool)conditionField.GetValue(target)); } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, showIfAttribute.ConditionName); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { return((bool)conditionMethod.Invoke(target, null)); } string warning = showIfAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, logToConsole: true, context: target); return(true); }
internal static List <bool> GetConditionValues(object target, string[] conditions) { List <bool> conditionValues = new List <bool>(); foreach (var condition in conditions) { FieldInfo conditionField = ReflectionUtility.GetField(target, condition); if (conditionField != null && conditionField.FieldType == typeof(bool)) { conditionValues.Add((bool)conditionField.GetValue(target)); } PropertyInfo conditionProperty = ReflectionUtility.GetProperty(target, condition); if (conditionProperty != null && conditionProperty.PropertyType == typeof(bool)) { conditionValues.Add((bool)conditionProperty.GetValue(target)); } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, condition); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { conditionValues.Add((bool)conditionMethod.Invoke(target, null)); } } return(conditionValues); }
private object GetValues(SerializedProperty property, string valuesName) { object target = PropertyUtility.GetTargetObjectWithProperty(property); FieldInfo valuesFieldInfo = ReflectionUtility.GetField(target, valuesName); if (valuesFieldInfo != null) { return(valuesFieldInfo.GetValue(target)); } PropertyInfo valuesPropertyInfo = ReflectionUtility.GetProperty(target, valuesName); if (valuesPropertyInfo != null) { return(valuesPropertyInfo.GetValue(target)); } MethodInfo methodValuesInfo = ReflectionUtility.GetMethod(target, valuesName); if (methodValuesInfo != null && methodValuesInfo.ReturnType != typeof(void) && methodValuesInfo.GetParameters().Length == 0) { return(methodValuesInfo.Invoke(target, null)); } return(null); }
/// <summary> /// Gets an enum value from reflection. /// </summary> /// <param name="target">The target object.</param> /// <param name="enumName">Name of a field, property, or method that returns an enum.</param> /// <returns>Null if can't find an enum value.</returns> internal static Enum GetEnumValue(object target, string enumName) { FieldInfo enumField = ReflectionUtility.GetField(target, enumName); if (enumField != null && enumField.FieldType.IsSubclassOf(typeof(Enum))) { return((Enum)enumField.GetValue(target)); } PropertyInfo enumProperty = ReflectionUtility.GetProperty(target, enumName); if (enumProperty != null && enumProperty.PropertyType.IsSubclassOf(typeof(Enum))) { return((Enum)enumProperty.GetValue(target)); } MethodInfo enumMethod = ReflectionUtility.GetMethod(target, enumName); if (enumMethod != null && enumMethod.ReturnType.IsSubclassOf(typeof(Enum))) { return((Enum)enumMethod.Invoke(target, null)); } return(null); }
public static void CallOnValueChangedCallbacks(SerializedProperty property) { object target = GetTargetObjectWithProperty(property); FieldInfo fieldInfo = ReflectionUtility.GetField(target, property.name); object oldValue = fieldInfo.GetValue(target); property.serializedObject.ApplyModifiedProperties(); // We must apply modifications so that the new value is updated in the serialized object object newValue = fieldInfo.GetValue(target); OnValueChangedAttribute[] onValueChangedAttributes = GetAttributes <OnValueChangedAttribute>(property); foreach (var onValueChangedAttribute in onValueChangedAttributes) { MethodInfo callbackMethod = ReflectionUtility.GetMethod(target, onValueChangedAttribute.CallbackName); if (callbackMethod != null && callbackMethod.ReturnType == typeof(void) && callbackMethod.GetParameters().Length == 2 || callbackMethod.GetParameters().Length == 0) { if (callbackMethod.GetParameters().Length == 0) { callbackMethod.Invoke(target, null); continue; } else if (callbackMethod.GetParameters().Length == 2) { ParameterInfo oldValueParam = callbackMethod.GetParameters()[0]; ParameterInfo newValueParam = callbackMethod.GetParameters()[1]; if (fieldInfo.FieldType == oldValueParam.ParameterType && fieldInfo.FieldType == newValueParam.ParameterType) { callbackMethod.Invoke(target, new object[] { oldValue, newValue }); continue; } else { string warning = string.Format( "The field '{0}' and the parameters of callback '{1}' must be of the same type." + Environment.NewLine + "Field={2}, Param0={3}, Param1={4}", fieldInfo.Name, callbackMethod.Name, fieldInfo.FieldType, oldValueParam.ParameterType, newValueParam.ParameterType); Debug.LogWarning(warning, property.serializedObject.targetObject); } } } { string warning = string.Format( "{0} can invoke only methods with 'void' return type and 0 parameters or 2 parameters of the same type as the field the attribute was put on", onValueChangedAttribute.GetType().Name); Debug.LogWarning(warning, property.serializedObject.targetObject); } } }
public override void ValidateProperty(SerializedProperty property, bool drawField) { ValidateInputAttribute validateInputAttribute = PropertyUtility.GetAttribute <ValidateInputAttribute>(property); if (validateInputAttribute.HideWithField && !drawField) { return; } UnityEngine.Object target = PropertyUtility.GetTargetObject(property); MethodInfo validationCallback = ReflectionUtility.GetMethod(target, validateInputAttribute.CallbackName); if (validationCallback != null && validationCallback.ReturnType == typeof(bool) && validationCallback.GetParameters().Length == 1) { FieldInfo fieldInfo = ReflectionUtility.GetField(target, property.name); Type fieldType = fieldInfo.FieldType; Type parameterType = validationCallback.GetParameters()[0].ParameterType; if (fieldType == parameterType) { if (!(bool)validationCallback.Invoke(target, new object[] { fieldInfo.GetValue(target) })) { if (string.IsNullOrEmpty(validateInputAttribute.Message)) { EditorDrawUtility.DrawHelpBox(property.name + " is not valid", MessageType.Error, logToConsole: true, context: target); } else { EditorDrawUtility.DrawHelpBox(validateInputAttribute.Message, MessageType.Error, logToConsole: true, context: target); } } } else { string warning = "The field type is not the same as the callback's parameter type"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, logToConsole: true, context: target); } } else { string warning = validateInputAttribute.GetType().Name + " needs a callback with boolean return type and a single parameter of the same type as the field"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, logToConsole: true, context: target); } }
private static AnimatorController GetAnimatorController(SerializedProperty property, string animatorName) { object target = PropertyUtility.GetTargetObjectWithProperty(property); FieldInfo animatorFieldInfo = ReflectionUtility.GetField(target, animatorName); if (animatorFieldInfo != null && animatorFieldInfo.FieldType == typeof(Animator)) { Animator animator = animatorFieldInfo.GetValue(target) as Animator; if (animator != null) { AnimatorController animatorController = animator.runtimeAnimatorController as AnimatorController; return(animatorController); } } PropertyInfo animatorPropertyInfo = ReflectionUtility.GetProperty(target, animatorName); if (animatorPropertyInfo != null && animatorPropertyInfo.PropertyType == typeof(Animator)) { Animator animator = animatorPropertyInfo.GetValue(target) as Animator; if (animator != null) { AnimatorController animatorController = animator.runtimeAnimatorController as AnimatorController; return(animatorController); } } MethodInfo animatorGetterMethodInfo = ReflectionUtility.GetMethod(target, animatorName); if (animatorGetterMethodInfo != null && animatorGetterMethodInfo.ReturnType == typeof(Animator) && animatorGetterMethodInfo.GetParameters().Length == 0) { Animator animator = animatorGetterMethodInfo.Invoke(target, null) as Animator; if (animator != null) { AnimatorController animatorController = animator.runtimeAnimatorController as AnimatorController; return(animatorController); } } return(null); }
public override void ValidateProperty(SerializedProperty property) { ValidateInputAttribute validateInputAttribute = PropertyUtility.GetAttribute <ValidateInputAttribute>(property); object target = PropertyUtility.GetTargetObjectWithProperty(property); MethodInfo validationCallback = ReflectionUtility.GetMethod(target, validateInputAttribute.CallbackName); if (validationCallback != null && validationCallback.ReturnType == typeof(bool) && validationCallback.GetParameters().Length == 1) { FieldInfo fieldInfo = ReflectionUtility.GetField(target, property.name); Type fieldType = fieldInfo.FieldType; Type parameterType = validationCallback.GetParameters()[0].ParameterType; if (fieldType == parameterType) { if (!(bool)validationCallback.Invoke(target, new object[] { fieldInfo.GetValue(target) })) { if (string.IsNullOrEmpty(validateInputAttribute.Message)) { NaughtyEditorGUI.HelpBox_Layout( property.name + " is not valid", MessageType.Error, context: property.serializedObject.targetObject); } else { NaughtyEditorGUI.HelpBox_Layout( validateInputAttribute.Message, MessageType.Error, context: property.serializedObject.targetObject); } } } else { string warning = "The field type is not the same as the callback's parameter type"; NaughtyEditorGUI.HelpBox_Layout(warning, MessageType.Warning, context: property.serializedObject.targetObject); } } else { string warning = validateInputAttribute.GetType().Name + " needs a callback with boolean return type and a single parameter of the same type as the field"; NaughtyEditorGUI.HelpBox_Layout(warning, MessageType.Warning, context: property.serializedObject.targetObject); } }
public override void ApplyPropertyMeta(SerializedProperty property, MetaAttribute metaAttribute) { var infoBoxAttribute = (InfoBoxAttribute)metaAttribute; var target = PropertyUtility.GetTargetObject(property); if (!string.IsNullOrEmpty(infoBoxAttribute.VisibleIf)) { var conditionField = ReflectionUtility.GetField(target, infoBoxAttribute.VisibleIf); if (conditionField != null && conditionField.FieldType == typeof(bool)) { if ((bool)conditionField.GetValue(target)) { DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } return; } var conditionMethod = ReflectionUtility.GetMethod(target, infoBoxAttribute.VisibleIf); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { if ((bool)conditionMethod.Invoke(target, null)) { DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } return; } var warning = infoBoxAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, PropertyUtility.GetTargetObject(property)); } else { DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } }
public override void ValidateProperty(SerializedProperty property) { var validateInputAttribute = PropertyUtility.GetAttribute <ValidateInputAttribute>(property); var target = PropertyUtility.GetTargetObject(property); var validationCallback = ReflectionUtility.GetMethod(target, validateInputAttribute.CallbackName); if (validationCallback != null && validationCallback.ReturnType == typeof(bool) && validationCallback.GetParameters().Length == 1) { var fieldInfo = ReflectionUtility.GetField(target, property.name); var fieldType = fieldInfo.FieldType; var parameterType = validationCallback.GetParameters()[0].ParameterType; if (fieldType == parameterType) { if (!(bool)validationCallback.Invoke(target, new[] { fieldInfo.GetValue(target) })) { if (string.IsNullOrEmpty(validateInputAttribute.Message)) { EditorDrawUtility.DrawHelpBox(property.name + " is not valid", MessageType.Error, target); } else { EditorDrawUtility.DrawHelpBox(validateInputAttribute.Message, MessageType.Error, target); } } } else { var warning = "The field type is not the same as the callback's parameter type"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, target); } } else { var warning = validateInputAttribute.GetType().Name + " needs a callback with boolean return type and a single parameter of the same type as the field"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, target); } }
public override bool CanDrawProperty(SerializedProperty property) { HideIfAnyAttribute[] hideIfAnyAttributes = PropertyUtility.GetAttributes <HideIfAnyAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); foreach (var attribute in hideIfAnyAttributes) { FieldInfo conditionField = ReflectionUtility.GetField(target, attribute.ConditionName); if (conditionField != null && conditionField.FieldType == typeof(bool)) { if ((bool)conditionField.GetValue(target) == attribute.ConditionValue) { return(false); } else { continue; } } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, attribute.ConditionName); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { if ((bool)conditionMethod.Invoke(target, null) == attribute.ConditionValue) { return(false); } else { continue; } } string warning = attribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, logToConsole: true, context: target); } return(true); }
public override void ApplyPropertyMeta(SerializedProperty property, MetaAttribute metaAttribute, bool drawField) { InfoBoxAttribute infoBoxAttribute = (InfoBoxAttribute)metaAttribute; UnityEngine.Object target = PropertyUtility.GetTargetObject(property); if (!string.IsNullOrEmpty(infoBoxAttribute.VisibleIf)) { FieldInfo conditionField = ReflectionUtility.GetField(target, infoBoxAttribute.VisibleIf); if (conditionField != null && conditionField.FieldType == typeof(bool)) { if ((bool)conditionField.GetValue(target)) { this.DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } return; } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, infoBoxAttribute.VisibleIf); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { if ((bool)conditionMethod.Invoke(target, null)) { this.DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } return; } string warning = infoBoxAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, logToConsole: true, context: PropertyUtility.GetTargetObject(property)); } else if (!infoBoxAttribute.HideWithField || (drawField && infoBoxAttribute.HideWithField)) { this.DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } }
public override void DrawProperty(SerializedProperty property) { bool drawEnabled = false; bool validCondition = false; EnableIfAttribute enableIfAttribute = PropertyUtility.GetAttribute <EnableIfAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo conditionField = ReflectionUtility.GetField(target, enableIfAttribute.ConditionName); if (conditionField != null && conditionField.FieldType == typeof(bool)) { drawEnabled = (bool)conditionField.GetValue(target); validCondition = true; } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, enableIfAttribute.ConditionName); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { drawEnabled = (bool)conditionMethod.Invoke(target, null); validCondition = true; } if (validCondition) { GUI.enabled = drawEnabled; EditorDrawUtility.DrawPropertyField(property); GUI.enabled = true; } else { string warning = enableIfAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, target); } }
private static List <bool> GetConditionValues(SerializedProperty property, string[] conditions) { var serializedObject = property.serializedObject; List <bool> conditionValues = new List <bool>(); var indexOfDot = property.propertyPath.LastIndexOf('.'); var outerPath = indexOfDot == -1 ? "" : property.propertyPath.Substring(0, indexOfDot); foreach (var condition in conditions) { var conditionPath = outerPath.Length == 0 ? condition : outerPath + "." + condition; var conditionProperty = serializedObject.FindProperty(conditionPath); if (conditionProperty != null && conditionProperty.propertyType == SerializedPropertyType.Boolean) { conditionValues.Add(conditionProperty.boolValue); } else { var target = GetTargetObjectWithProperty(property); var reflectionProperty = ReflectionUtility.GetProperty(target, condition); if (reflectionProperty != null && reflectionProperty.PropertyType == typeof(bool)) { conditionValues.Add((bool)reflectionProperty.GetValue(target)); } else { var reflectionMethod = ReflectionUtility.GetMethod(target, condition); if (reflectionMethod != null && reflectionMethod.ReturnType == typeof(bool) && reflectionMethod.GetParameters().Length == 0) { conditionValues.Add((bool)reflectionMethod.Invoke(target, null)); } } } } return(conditionValues); }
public override void ApplyPropertyMeta(SerializedProperty property, MetaAttribute metaAttribute) { OnValueChangedAttribute onValueChangedAttribute = (OnValueChangedAttribute)metaAttribute; UnityEngine.Object target = PropertyUtility.GetTargetObject(property); MethodInfo callbackMethod = ReflectionUtility.GetMethod(target, onValueChangedAttribute.CallbackName); if (callbackMethod != null && callbackMethod.ReturnType == typeof(void) && callbackMethod.GetParameters().Length == 0) { property.serializedObject.ApplyModifiedProperties(); // We must apply modifications so that the callback can be invoked with up-to-date data callbackMethod.Invoke(target, null); } else { string warning = onValueChangedAttribute.GetType().Name + " can invoke only action methods - with void return type and no parameters"; Debug.LogWarning(warning, target); } }
public override bool CanDrawProperty(SerializedProperty property) { ShowIfAttribute showIfAttribute = PropertyUtility.GetAttribute <ShowIfAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); List <bool> conditionValues = new List <bool>(); foreach (var condition in showIfAttribute.Conditions) { FieldInfo conditionField = ReflectionUtility.GetField(target, condition); if (conditionField != null && conditionField.FieldType == typeof(bool)) { conditionValues.Add((bool)conditionField.GetValue(target)); } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, condition); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { conditionValues.Add((bool)conditionMethod.Invoke(target, null)); } } if (conditionValues.Count > 0) { bool draw; if (showIfAttribute.ConditionOperator == ConditionOperator.And) { draw = true; foreach (var value in conditionValues) { draw = draw && value; } } else { draw = false; foreach (var value in conditionValues) { draw = draw || value; } } if (showIfAttribute.Reversed) { draw = !draw; } return(draw); } else { string warning = showIfAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: target); return(true); } }
public override void DrawProperty(SerializedProperty property) { EnableIfAttribute enableIfAttribute = PropertyUtility.GetAttribute <EnableIfAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); List <bool> conditionValues = new List <bool>(); foreach (var condition in enableIfAttribute.Conditions) { FieldInfo conditionField = ReflectionUtility.GetField(target, condition); if (conditionField?.FieldType == typeof(bool)) { conditionValues.Add((bool)conditionField.GetValue(target)); } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, condition); if (conditionMethod?.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { conditionValues.Add((bool)conditionMethod.Invoke(target, null)); } PropertyInfo conditionProperty = ReflectionUtility.GetProperty(target, condition); if (conditionProperty?.PropertyType == typeof(bool)) { conditionValues.Add((bool)conditionProperty.GetValue(target)); } } if (conditionValues.Count > 0) { bool enabled; if (enableIfAttribute.ConditionOperator == ConditionOperator.And) { enabled = true; foreach (var value in conditionValues) { enabled = enabled && value; } } else { enabled = false; foreach (var value in conditionValues) { enabled = enabled || value; } } if (enableIfAttribute.Reversed) { enabled = !enabled; } GUI.enabled = enabled; EditorDrawUtility.DrawPropertyField(property); GUI.enabled = true; } else { string warning = enableIfAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: target); } }
public override void DrawMethod(UnityEngine.Object target, MethodInfo methodInfo) { ButtonIfAttribute buttonIfAttribute = (ButtonIfAttribute)methodInfo.GetCustomAttributes(typeof(ButtonIfAttribute), true)[0]; List <bool> conditionValues = new List <bool>(); foreach (var condition in buttonIfAttribute.Conditions) { //Debug.Log("condition: " + condition); FieldInfo conditionField = ReflectionUtility.GetField(target, condition); if (conditionField != null && conditionField.FieldType == typeof(bool)) { conditionValues.Add((bool)conditionField.GetValue(target)); } MethodInfo conditionMethod = ReflectionUtility.GetMethod(target, condition); if (conditionMethod != null && conditionMethod.ReturnType == typeof(bool) && conditionMethod.GetParameters().Length == 0) { //Debug.Log("method found: " + condition); conditionValues.Add((bool)conditionMethod.Invoke(target, null)); } } bool enabled = false; if (conditionValues.Count > 0) { if (buttonIfAttribute.ConditionOperator == ConditionOperator.And) { enabled = true; foreach (var value in conditionValues) { enabled = enabled && value; } } else { enabled = false; foreach (var value in conditionValues) { enabled = enabled || value; } } if (buttonIfAttribute.Reversed) { enabled = !enabled; } } else { string warning = buttonIfAttribute.GetType().Name + " needs a valid boolean condition field or method name to work"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: target); return; } if (methodInfo.GetParameters().Length == 0) { string buttonText = string.IsNullOrEmpty(buttonIfAttribute.Text) ? methodInfo.Name : buttonIfAttribute.Text; GUI.enabled = enabled; if (GUILayout.Button(buttonText)) { methodInfo.Invoke(target, null); } GUI.enabled = true; if (!enabled) { string infoText = "Preconditions for " + buttonText + ":"; for (int ix = 0; ix < conditionValues.Count; ix++) { infoText += "\n "; if (ix > 0) { infoText += buttonIfAttribute.ConditionOperator + " "; } infoText += buttonIfAttribute.Conditions[ix]; infoText += " (" + conditionValues[ix] + ")"; } EditorGUILayout.HelpBox(infoText, MessageType.Info); } } else { string warning = typeof(ButtonIfAttribute).Name + " works only on methods with no parameters"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: target); } }