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));
            }
        }
示例#2
0
        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));
            }
        }
示例#5
0
        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);
        }
示例#7
0
        //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);
            }
        }
示例#9
0
        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);
                }
            }
        }
示例#11
0
        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);
        }
示例#12
0
        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);
            }
        }
示例#13
0
        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);
        }
示例#14
0
        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);
            }
        }
示例#15
0
        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);
                }
            }
        }
示例#16
0
        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);
            }
        }