public override void ValidateProperty(SerializedProperty property) { RequiredAttribute requiredAttribute = PropertyUtility.GetAttributes <RequiredAttribute>(property)[0]; if (property.propertyType == SerializedPropertyType.ObjectReference) { if (property.objectReferenceValue == null) { string errorMessage = property.name + " is required"; if (!string.IsNullOrEmpty(requiredAttribute.Message)) { errorMessage = requiredAttribute.Message; } EditorGUILayout.HelpBox(errorMessage, MessageType.Error); Debug.LogError(errorMessage, PropertyUtility.GetTargetObject(property)); } } else { string warning = requiredAttribute.GetType().Name + " works only on reference types"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); } }
public override void DrawProperty(SerializedProperty property) { if (property.propertyType != SerializedPropertyType.Float && property.propertyType != SerializedPropertyType.Integer) { EditorGUILayout.HelpBox("Field " + property.name + " is not a number", MessageType.Warning); return; } var value = property.propertyType == SerializedPropertyType.Integer ? property.intValue : property.floatValue; var valueFormatted = property.propertyType == SerializedPropertyType.Integer ? value.ToString() : String.Format("{0:0.00}", value); ProgressBarAttribute progressBarAttribute = PropertyUtility.GetAttributes <ProgressBarAttribute>(property)[0]; var position = EditorGUILayout.GetControlRect(); var maxValue = progressBarAttribute.MaxValue; float lineHight = EditorGUIUtility.singleLineHeight; float padding = EditorGUIUtility.standardVerticalSpacing; var barPosition = new Rect(position.position.x, position.position.y, position.size.x, lineHight); var fillPercentage = value / maxValue; var barLabel = (!string.IsNullOrEmpty(progressBarAttribute.Name) ? "[" + progressBarAttribute.Name + "] " : "") + valueFormatted + "/" + maxValue; var color = GetColor(progressBarAttribute.Color); var color2 = Color.white; DrawBar(barPosition, Mathf.Clamp01(fillPercentage), barLabel, color, color2); }
public sealed override void OnGUI(Rect rect, SerializedProperty property, GUIContent label) { // Check if visible bool visible = PropertyUtility.IsVisible(property); if (!visible) { return; } // Validate ValidatorAttribute[] validatorAttributes = PropertyUtility.GetAttributes <ValidatorAttribute>(property); foreach (var validatorAttribute in validatorAttributes) { validatorAttribute.GetValidator().ValidateProperty(property); } // Check if enabled and draw EditorGUI.BeginChangeCheck(); bool enabled = PropertyUtility.IsEnabled(property); using (new EditorGUI.DisabledScope(disabled: !enabled)) { OnGUI_Internal(rect, property, PropertyUtility.GetLabel(property)); } // Call OnValueChanged callbacks if (EditorGUI.EndChangeCheck()) { PropertyUtility.CallOnValueChangedCallbacks(property); } }
public override void ValidateProperty(SerializedProperty property) { MinValueAttribute minValueAttribute = PropertyUtility.GetAttributes <MinValueAttribute>(property)[0]; if (property.propertyType == SerializedPropertyType.Integer) { if (property.intValue < minValueAttribute.MinValue) { property.intValue = (int)minValueAttribute.MinValue; } } else if (property.propertyType == SerializedPropertyType.Float) { if (property.floatValue < minValueAttribute.MinValue) { property.floatValue = minValueAttribute.MinValue; } } else { string warning = minValueAttribute.GetType().Name + " can be used only on int or float fields"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); } }
public override void DrawProperty(SerializedProperty property) { EditorGUILayout.PropertyField(property, true); if (property.propertyType == SerializedPropertyType.ObjectReference) { if (property.objectReferenceValue != null) { Texture2D previewTexture = AssetPreview.GetAssetPreview(property.objectReferenceValue); if (previewTexture != null) { ShowAssetPreviewAttribute showAssetPreviewAttribute = PropertyUtility.GetAttributes <ShowAssetPreviewAttribute>(property)[0]; int width = Mathf.Clamp(showAssetPreviewAttribute.Width, 0, previewTexture.width); int height = Mathf.Clamp(showAssetPreviewAttribute.Height, 0, previewTexture.height); GUILayout.Label(previewTexture, GUILayout.MaxWidth(width), GUILayout.MaxHeight(height)); } else { this.DrawWarningBox(property.name + " doesn't have an asset preview", property); } } } else { this.DrawWarningBox(property.name + " doesn't have an asset preview", property); } }
public override bool CanDrawProperty(SerializedProperty property) { ShowIfAttribute showIfAttribute = PropertyUtility.GetAttributes <ShowIfAttribute>(property)[0]; UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo conditionField = target.GetType().GetField(showIfAttribute.ConditionName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (conditionField != null && conditionField.FieldType == typeof(bool)) { return((bool)conditionField.GetValue(target)); } MethodInfo conditionMethod = target.GetType().GetMethod(showIfAttribute.ConditionName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 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"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, target); return(true); }
//OnEditor public void OnGUI(SerializedProperty property) { // Check if visible bool visible = PropertyUtility.IsVisible(property); if (!visible) { return; } // Validate ValidatorAttribute[] validatorAttributes = PropertyUtility.GetAttributes <ValidatorAttribute>(property); foreach (var validatorAttribute in validatorAttributes) { validatorAttribute.GetValidator().ValidateProperty(property); } // Check if enabled and draw EditorGUI.BeginChangeCheck(); bool enabled = PropertyUtility.IsEnabled(property); GUI.enabled = enabled; OnGUI_Internal(property, new GUIContent(PropertyUtility.GetLabel(property))); GUI.enabled = true; // Call OnValueChanged callbacks if (EditorGUI.EndChangeCheck()) { PropertyUtility.CallOnValueChangedCallbacks(property); } }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); if (property.propertyType == SerializedPropertyType.String) { EditorGUILayout.LabelField(property.displayName); EditorGUI.BeginChangeCheck(); string textAreaValue = EditorGUILayout.TextArea(property.stringValue, GUILayout.MinHeight(EditorGUIUtility.singleLineHeight * 3f)); if (EditorGUI.EndChangeCheck()) { property.stringValue = textAreaValue; } } else { string warning = PropertyUtility.GetAttributes <ResizableTextAreaAttribute>(property)[0].GetType().Name + " can only be used on string fields"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); } }
private static void PropertyField_Implementation(Rect rect, SerializedProperty property, bool includeChildren, PropertyFieldFunction propertyFieldFunction) { SpecialCaseDrawerAttribute specialCaseAttribute = PropertyUtility.GetAttribute <SpecialCaseDrawerAttribute>(property); if (specialCaseAttribute != null) { specialCaseAttribute.GetDrawer().OnGUI(rect, property); } else { GUIContent label = new GUIContent(PropertyUtility.GetLabel(property)); bool anyDrawerAttribute = PropertyUtility.GetAttributes <DrawerAttribute>(property).Any(); if (!anyDrawerAttribute) { // Drawer attributes check for visibility, enableability and validator themselves, // so if a property doesn't have a DrawerAttribute we need to check for these explicitly // Check if visible bool visible = PropertyUtility.IsVisible(property); if (!visible) { return; } // Validate ValidatorAttribute[] validatorAttributes = PropertyUtility.GetAttributes <ValidatorAttribute>(property); foreach (var validatorAttribute in validatorAttributes) { validatorAttribute.GetValidator().ValidateProperty(property); } // Check if enabled and draw EditorGUI.BeginChangeCheck(); bool enabled = PropertyUtility.IsEnabled(property); using (new EditorGUI.DisabledScope(disabled: !enabled)) { propertyFieldFunction.Invoke(rect, property, label, includeChildren); } // Call OnValueChanged callbacks if (EditorGUI.EndChangeCheck()) { PropertyUtility.CallOnValueChangedCallbacks(property); } } else { // We don't need to check for enableIfAttribute propertyFieldFunction.Invoke(rect, property, label, includeChildren); } } }
public static void PropertyField_Layout(SerializedProperty property, bool includeChildren) { SpecialCaseDrawerAttribute specialCaseAttribute = PropertyUtility.GetAttribute <SpecialCaseDrawerAttribute>(property); if (specialCaseAttribute != null) { specialCaseAttribute.GetDrawer().OnGUI(property); } else { GUIContent label = new GUIContent(PropertyUtility.GetLabel(property)); bool anyDrawerAttribute = PropertyUtility.GetAttributes <DrawerAttribute>(property).Any(); if (!anyDrawerAttribute) { // Drawer attributes check for visibility, enableability and validator themselves, // so if a property doesn't have a DrawerAttribute we need to check for these explicitly // Check if visible bool visible = PropertyUtility.IsVisible(property); if (!visible) { return; } // Validate ValidatorAttribute[] validatorAttributes = PropertyUtility.GetAttributes <ValidatorAttribute>(property); foreach (var validatorAttribute in validatorAttributes) { validatorAttribute.GetValidator().ValidateProperty(property); } // Check if enabled and draw EditorGUI.BeginChangeCheck(); bool enabled = PropertyUtility.IsEnabled(property); GUI.enabled = enabled; EditorGUILayout.PropertyField(property, label, includeChildren); GUI.enabled = true; // Call OnValueChanged callbacks if (EditorGUI.EndChangeCheck()) { PropertyUtility.CallOnValueChangedCallbacks(property); } } else { // We don't need to check for enableIfAttribute EditorGUILayout.PropertyField(property, label, includeChildren); } } }
public static NaughtyProperty CreateNaughtyProperty(SerializedProperty serializedProperty) { NaughtyProperty naughtyProperty = new NaughtyProperty(); naughtyProperty.serializedProperty = serializedProperty; naughtyProperty.readOnlyAttribute = PropertyUtility.GetAttribute <ReadOnlyAttribute>(serializedProperty); naughtyProperty.enableIfAttribute = PropertyUtility.GetAttribute <EnableIfAttributeBase>(serializedProperty); naughtyProperty.showIfAttribute = PropertyUtility.GetAttribute <ShowIfAttributeBase>(serializedProperty); naughtyProperty.validatorAttributes = PropertyUtility.GetAttributes <ValidatorAttribute>(serializedProperty); naughtyProperty.labelAttribute = PropertyUtility.GetAttribute <LabelAttribute>(serializedProperty); naughtyProperty.specialCaseDrawerAttribute = PropertyUtility.GetAttribute <SpecialCaseDrawerAttribute>(serializedProperty); return(naughtyProperty); }
public override void ValidateProperty(SerializedProperty property) { ValidateInputAttribute validateInputAttribute = PropertyUtility.GetAttributes <ValidateInputAttribute>(property)[0]; UnityEngine.Object target = PropertyUtility.GetTargetObject(property); MethodInfo validationCallback = target.GetType().GetMethod(validateInputAttribute.CallbackName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (validationCallback != null && validationCallback.ReturnType == typeof(bool) && validationCallback.GetParameters().Length == 1) { FieldInfo fieldInfo = target.GetType().GetField(property.name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 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)) { this.DrawHelpBox(property.name + " is not valid", target, MessageType.Error); } else { this.DrawHelpBox(validateInputAttribute.Message, target, MessageType.Error); } } } else { this.DrawHelpBox("The field type is not the same as the callback's parameter type", target, MessageType.Warning); } } else { this.DrawHelpBox(validateInputAttribute.GetType().Name + " needs a callback with boolean return type and a single parameter of the same type as the field", target, MessageType.Warning); } }
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 DrawProperty(SerializedProperty property) { SliderAttribute sliderAttribute = PropertyUtility.GetAttributes <SliderAttribute>(property)[0]; if (property.propertyType == SerializedPropertyType.Integer) { EditorGUILayout.IntSlider(property, (int)sliderAttribute.MinValue, (int)sliderAttribute.MaxValue); } else if (property.propertyType == SerializedPropertyType.Float) { EditorGUILayout.Slider(property, sliderAttribute.MinValue, sliderAttribute.MaxValue); } else { string warning = sliderAttribute.GetType().Name + " can be used only on int or float fields"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); EditorGUILayout.PropertyField(property, true); } }
private static void PropertyField_Implementation(Rect rect, SerializedProperty property, bool includeChildren, PropertyFieldFunction propertyFieldFunction) { SpecialCaseDrawerAttribute specialCaseAttribute = PropertyUtility.GetAttribute <SpecialCaseDrawerAttribute>(property); if (specialCaseAttribute != null) { specialCaseAttribute.GetDrawer().OnGUI(rect, property); } else { // Check if visible bool visible = PropertyUtility.IsVisible(property); if (!visible) { return; } // Validate ValidatorAttribute[] validatorAttributes = PropertyUtility.GetAttributes <ValidatorAttribute>(property); foreach (var validatorAttribute in validatorAttributes) { validatorAttribute.GetValidator().ValidateProperty(property); } // Check if enabled and draw EditorGUI.BeginChangeCheck(); bool enabled = PropertyUtility.IsEnabled(property); using (new EditorGUI.DisabledScope(disabled: !enabled)) { propertyFieldFunction.Invoke(rect, property, PropertyUtility.GetLabel(property), includeChildren); } // Call OnValueChanged callbacks if (EditorGUI.EndChangeCheck()) { PropertyUtility.CallOnValueChangedCallbacks(property); } } }
public override void DrawProperty(SerializedProperty property) { DropdownAttribute dropdownAttribute = PropertyUtility.GetAttributes <DropdownAttribute>(property)[0]; UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo fieldInfo = target.GetType().GetField(property.name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); FieldInfo valuesFieldInfo = target.GetType().GetField(dropdownAttribute.ValuesFieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); if (valuesFieldInfo == null) { this.DrawWarningBox(string.Format("{0} cannot find a values field with name \"{1}\"", dropdownAttribute.GetType().Name, dropdownAttribute.ValuesFieldName)); EditorGUILayout.PropertyField(property, true); } else if (fieldInfo.FieldType == valuesFieldInfo.FieldType.GetElementType()) { // Selected value object selectedValue = fieldInfo.GetValue(target); // Values and display options IList valuesList = (IList)valuesFieldInfo.GetValue(target); object[] values = new object[valuesList.Count]; string[] displayOptions = new string[valuesList.Count]; for (int i = 0; i < values.Length; i++) { object value = valuesList[i]; values[i] = value; displayOptions[i] = value.ToString(); } // Selected value index int selectedValueIndex = Array.IndexOf(values, selectedValue); if (selectedValueIndex < 0) { selectedValueIndex = 0; } // Draw the dropdown this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values, displayOptions); } else if (valuesFieldInfo.GetValue(target) is IDropdownList) { // Current value object selectedValue = fieldInfo.GetValue(target); // Current value index, values and display options IDropdownList dropdown = (IDropdownList)valuesFieldInfo.GetValue(target); IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator(); int index = -1; int selectedValueIndex = -1; List <object> values = new List <object>(); List <string> displayOptions = new List <string>(); while (dropdownEnumerator.MoveNext()) { index++; KeyValuePair <string, object> current = dropdownEnumerator.Current; if (current.Value.Equals(selectedValue)) { selectedValueIndex = index; } values.Add(current.Value); displayOptions.Add(current.Key); } if (selectedValueIndex < 0) { selectedValueIndex = 0; } // Draw the dropdown this.DrawDropdown(target, fieldInfo, property.displayName, selectedValueIndex, values.ToArray(), displayOptions.ToArray()); } else { this.DrawWarningBox(typeof(DropdownAttribute).Name + " works only when the type of the field is equal to the element type of the array"); EditorGUILayout.PropertyField(property, true); } }
public override void DrawProperty(SerializedProperty property) { MinMaxSliderAttribute minMaxSliderAttribute = PropertyUtility.GetAttributes <MinMaxSliderAttribute>(property)[0]; if (property.propertyType == SerializedPropertyType.Vector2) { Rect controlRect = EditorGUILayout.GetControlRect(); float labelWidth = EditorGUIUtility.labelWidth; float floatFieldWidth = EditorGUIUtility.fieldWidth; float sliderWidth = controlRect.width - labelWidth - 2f * floatFieldWidth; float sliderPadding = 5f; Rect labelRect = new Rect( controlRect.x, controlRect.y, labelWidth, controlRect.height); Rect sliderRect = new Rect( controlRect.x + labelWidth + floatFieldWidth + sliderPadding, controlRect.y, sliderWidth - 2f * sliderPadding, controlRect.height); Rect minFloatFieldRect = new Rect( controlRect.x + labelWidth, controlRect.y, floatFieldWidth, controlRect.height); Rect maxFloatFieldRect = new Rect( controlRect.x + labelWidth + floatFieldWidth + sliderWidth, controlRect.y, floatFieldWidth, controlRect.height); // Draw the label EditorGUI.LabelField(labelRect, property.displayName); // Draw the slider EditorGUI.BeginChangeCheck(); Vector2 sliderValue = property.vector2Value; EditorGUI.MinMaxSlider(sliderRect, ref sliderValue.x, ref sliderValue.y, minMaxSliderAttribute.MinValue, minMaxSliderAttribute.MaxValue); sliderValue.x = EditorGUI.FloatField(minFloatFieldRect, sliderValue.x); sliderValue.x = Mathf.Clamp(sliderValue.x, minMaxSliderAttribute.MinValue, Mathf.Min(minMaxSliderAttribute.MaxValue, sliderValue.y)); sliderValue.y = EditorGUI.FloatField(maxFloatFieldRect, sliderValue.y); sliderValue.y = Mathf.Clamp(sliderValue.y, Mathf.Max(minMaxSliderAttribute.MinValue, sliderValue.x), minMaxSliderAttribute.MaxValue); if (EditorGUI.EndChangeCheck()) { property.vector2Value = sliderValue; } } else { string warning = minMaxSliderAttribute.GetType().Name + " can be used only on Vector2 fields"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); EditorGUILayout.PropertyField(property, true); } }