public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); if (property.isArray) { var listView = GetListView(property); listView.DoLayoutList(); if (listView.HasKeyboardControl()) { if (Event.current.type == EventType.KeyDown) { if (Event.current.keyCode == KeyCode.Delete || Event.current.keyCode == KeyCode.KeypadMinus) { if (listView.onCanRemoveCallback(listView)) { listView.onRemoveCallback(listView); } } else if (Event.current.keyCode == KeyCode.KeypadPlus) { listView.onAddCallback(listView); } } } } else { string warning = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(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); } }
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 ValidateProperty(SerializedProperty property) { MinValueAttribute minValueAttribute = PropertyUtility.GetAttribute <MinValueAttribute>(property); 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 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"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, logToConsole: true, context: target); return(true); }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawPropertyField(property); if (property.propertyType == SerializedPropertyType.ObjectReference) { if (property.objectReferenceValue != null) { Texture2D previewTexture = AssetPreview.GetAssetPreview(property.objectReferenceValue); if (previewTexture != null) { ShowAssetPreviewAttribute showAssetPreviewAttribute = PropertyUtility.GetAttribute <ShowAssetPreviewAttribute>(property); 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 { string warning = property.name + " doesn't have an asset preview"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: PropertyUtility.GetTargetObject(property)); } } } else { string warning = property.name + " doesn't have an asset preview"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: PropertyUtility.GetTargetObject(property)); } }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); var attr = PropertyUtility.GetAttribute <PowerSlideAttribute>(property); if (attr.BaseRcpLn == 0 | attr.BaseRcpLn == float.NaN) { EditorDrawUtility.DrawHelpBox($"Invalid Base: {attr.Base}", MessageType.Warning, context: PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); return; } if (property.propertyType == SerializedPropertyType.Integer) { float value = math.log(property.intValue) * attr.BaseRcpLn; EditorGUI.BeginChangeCheck(); EditorGUILayout.PrefixLabel($"{property.displayName}[{property.intValue}]"); value = EditorGUILayout.Slider(value, attr.MinPower, attr.MaxPower); property.intValue = (int)math.round(math.pow(attr.Base, value)); } else if (property.propertyType == SerializedPropertyType.Float) { float value = math.log(property.floatValue) * attr.BaseRcpLn; EditorGUI.BeginChangeCheck(); EditorGUILayout.PrefixLabel($"{property.displayName}[{property.floatValue}]"); value = EditorGUILayout.Slider(value, attr.MinPower, attr.MaxPower); property.floatValue = math.pow(attr.Base, value); } else { string warning = attr.GetType().Name + " can be used only on int or float fields"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(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); }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); if (property.isArray) { if (!this.reorderableListsByPropertyName.ContainsKey(property.name)) { ReorderableList reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true) { drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, string.Format("{0}: {1}", property.displayName, property.arraySize), EditorStyles.label); }, drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = property.GetArrayElementAtIndex(index); rect.y += 2f; var key = ""; if (element != null && element.objectReferenceValue != null) { key = element.objectReferenceValue.GetType().GetField("Key").GetValue(element.objectReferenceValue) as string; } using (var scope = new EditorGUILayout.HorizontalScope()) { EditorGUI.LabelField(new Rect(rect.x, rect.y, 30, EditorGUIUtility.singleLineHeight), "Key"); key = EditorGUI.TextField(new Rect(rect.x + 30, rect.y, rect.width * 0.3f, EditorGUIUtility.singleLineHeight), key); if (element != null && element.objectReferenceValue != null) { element.objectReferenceValue.GetType().GetField("Key").SetValue(element.objectReferenceValue, key); } EditorGUIUtility.labelWidth = 53; EditorGUI.PropertyField(new Rect(rect.x + 30 + rect.width * 0.35f, rect.y, rect.width * 0.65f - 30, EditorGUIUtility.singleLineHeight), element); } } }; this.reorderableListsByPropertyName[property.name] = reorderableList; } this.reorderableListsByPropertyName[property.name].DoLayoutList(); } else { string warning = typeof(ReorderableKeyListAttribute).Name + " can be used only on arrays or lists"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); } }
private void GetComponent() { var monoBehaviour = PropertyUtility.GetTargetObject(property) as MonoBehaviour; if (property.isArray) { GetComponents(monoBehaviour); } else { GetSingleComponent(monoBehaviour); } }
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); } }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); if (property.isArray) { var key = GetPropertyKeyName(property); if (!this.reorderableListsByPropertyName.ContainsKey(key)) { ReorderableList reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true) { drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, string.Format("{0}: {1}", property.displayName, property.arraySize), EditorStyles.label); }, drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = property.GetArrayElementAtIndex(index); rect.y += 1.0f; rect.x += 10.0f; rect.width -= 10.0f; EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, 0.0f), element, true); }, elementHeightCallback = (int index) => { return(EditorGUI.GetPropertyHeight(property.GetArrayElementAtIndex(index)) + 4.0f); } }; this.reorderableListsByPropertyName[key] = reorderableList; } this.reorderableListsByPropertyName[key].DoLayoutList(); } else { string warning = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); } }
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 void ApplyPropertyMeta(SerializedProperty property, MetaAttribute metaAttribute) { InfoBoxAttribute infoBoxAttribute = (InfoBoxAttribute)metaAttribute; UnityEngine.Object target = PropertyUtility.GetTargetObject(property); if (!string.IsNullOrEmpty(infoBoxAttribute.VisibleIf)) { FieldInfo conditionField = target.GetType().GetField(infoBoxAttribute.VisibleIf, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (conditionField != null && conditionField.FieldType == typeof(bool)) { if ((bool)conditionField.GetValue(target)) { this.DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } return; } MethodInfo conditionMethod = target.GetType().GetMethod(infoBoxAttribute.VisibleIf, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 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"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); } else { this.DrawInfoBox(infoBoxAttribute.Text, infoBoxAttribute.Type); } }
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) { if (property.propertyType == SerializedPropertyType.String) { AnimatorTypeAttribute typeAttribute = PropertyUtility.GetAttribute <AnimatorTypeAttribute>(property); UnityEngine.Object target = PropertyUtility.GetTargetObject(property); FieldInfo fieldInfo = ReflectionUtility.GetField(target, property.name); FieldInfo animatorInfo = ReflectionUtility.GetField(target, typeAttribute.FieldName); Animator animator = (Animator)animatorInfo.GetValue(target); if (animatorInfo == null || !animator) { this.DrawWarningBox(string.Format("Cannot find a values field with given name")); EditorGUILayout.PropertyField(property, true); } else { List <string> allNames = new List <string>(); string propertyValue = property.stringValue; int index = 0; for (int i = 0; i < animator.parameters.Length; i++) { if (animator.parameters[i].type == typeAttribute.Type) { allNames.Add(animator.parameters[i].name); if (animator.parameters[i].name == propertyValue) { index = allNames.Count - 1; } } } string[] results = allNames.ToArray(); DrawDropdown(target, fieldInfo, property.displayName, index, results, results); } } }
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 void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); var sliderAttribute = PropertyUtility.GetAttribute <SliderAttribute>(property); 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 { var warning = sliderAttribute.GetType().Name + " can be used only on int or float fields"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); } }
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); } }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); if (property.isArray) { var key = GetPropertyKeyName(property); if (!reorderableListsByPropertyName.ContainsKey(key)) { var reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true) { drawHeaderCallback = rect => { EditorGUI.LabelField( rect, string.Format("{0}: {1}", property.displayName, property.arraySize), EditorStyles.label); }, drawElementCallback = (rect, index, isActive, isFocused) => { var element = property.GetArrayElementAtIndex(index); rect.y += 2f; EditorGUI.PropertyField( new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element); } }; reorderableListsByPropertyName[key] = reorderableList; } reorderableListsByPropertyName[key].DoLayoutList(); } else { var warning = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); } }
public override void ApplyPropertyMeta(SerializedProperty property, MetaAttribute metaAttribute) { OnValueChangedAttribute onValueChangedAttribute = (OnValueChangedAttribute)metaAttribute; UnityEngine.Object target = PropertyUtility.GetTargetObject(property); MethodInfo callbackMethod = target.GetType().GetMethod(onValueChangedAttribute.CallbackName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 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 void ApplyPropertyMeta(SerializedProperty property, MetaAttribute metaAttribute) { var onValueChangedAttribute = (OnValueChangedAttribute)metaAttribute; var target = PropertyUtility.GetTargetObject(property); var 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 { var warning = onValueChangedAttribute.GetType().Name + " can invoke only action methods - with void return type and no parameters"; Debug.LogWarning(warning, target); } }
public override void DrawProperty(SerializedProperty property) { if (property.isArray) { if (!this.reorderableListsByPropertyName.ContainsKey(property.name)) { ReorderableList reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true) { drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, string.Format("{0}: {1}", property.displayName, property.arraySize), EditorStyles.label); }, drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = property.GetArrayElementAtIndex(index); rect.y += 2f; EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element); } }; this.reorderableListsByPropertyName[property.name] = reorderableList; } this.reorderableListsByPropertyName[property.name].DoLayoutList(); } else { string warning = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); EditorGUILayout.PropertyField(property, true); } }
public override void ValidateProperty(SerializedProperty property) { MaxValueAttribute maxValueAttribute = PropertyUtility.GetAttribute <MaxValueAttribute>(property); if (property.propertyType == SerializedPropertyType.Integer) { if (property.intValue > maxValueAttribute.MaxValue) { property.intValue = (int)maxValueAttribute.MaxValue; } } else if (property.propertyType == SerializedPropertyType.Float) { if (property.floatValue > maxValueAttribute.MaxValue) { property.floatValue = maxValueAttribute.MaxValue; } } else { string warning = maxValueAttribute.GetType().Name + " can be used only on int or float fields"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: PropertyUtility.GetTargetObject(property)); } }
public override void ValidateProperty(SerializedProperty property) { var requiredAttribute = PropertyUtility.GetAttribute <RequiredAttribute>(property); if (property.propertyType == SerializedPropertyType.ObjectReference) { if (property.objectReferenceValue == null) { var errorMessage = property.name + " is required"; if (!string.IsNullOrEmpty(requiredAttribute.Message)) { errorMessage = requiredAttribute.Message; } EditorDrawUtility.DrawHelpBox(errorMessage, MessageType.Error, PropertyUtility.GetTargetObject(property)); } } else { var warning = requiredAttribute.GetType().Name + " works only on reference types"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, PropertyUtility.GetTargetObject(property)); } }
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); } }
private void DrawWarningBox(string warningText, SerializedProperty property) { EditorGUILayout.HelpBox(warningText, MessageType.Warning); Debug.LogWarning(warningText, PropertyUtility.GetTargetObject(property)); }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); if (property.isArray) { var targetObject = property.serializedObject.targetObject; var propInfo = targetObject.GetType().GetField(property.name); var listObj = (IList)propInfo.GetValue(targetObject); if (!this.reorderableListsByPropertyName.ContainsKey(property.name)) { ReorderableList reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true) { drawHeaderCallback = (Rect rect) => { EditorGUI.LabelField(rect, string.Format("{0}: {1}", property.displayName, property.arraySize), EditorStyles.label); }, drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { rect.y += 2f; var elementObj = listObj[index]; var element = property.GetArrayElementAtIndex(index); float y = rect.y; var allElementFileds = elementObj.GetType().GetFields(); for (int i = 0; i < allElementFileds.Length; i++) { var elementChildProp = element.FindPropertyRelative(allElementFileds[i].Name); if (elementChildProp == null) { continue; } EditorGUI.PropertyField(new Rect(rect.x, y, rect.width, EditorGUIUtility.singleLineHeight), elementChildProp); y += 20; rect.y = y; } } }; reorderableList.elementHeightCallback = (int index) => { var element = property.GetArrayElementAtIndex(index); var elementObj = listObj[index]; var allElementFileds = elementObj.GetType().GetFields(); int y = 0; for (int i = 0; i < allElementFileds.Length; i++) { var elementChildProp = element.FindPropertyRelative(allElementFileds[i].Name); if (elementChildProp == null) { continue; } y += 22; } return(y); }; this.reorderableListsByPropertyName[property.name] = reorderableList; } this.reorderableListsByPropertyName[property.name].DoLayoutList(); } else { string warning = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists"; EditorGUILayout.HelpBox(warning, MessageType.Warning); Debug.LogWarning(warning, PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); } }
public override void DrawProperty(SerializedProperty property) { EditorDrawUtility.DrawHeader(property); var minMaxSliderAttribute = PropertyUtility.GetAttribute <MinMaxSliderAttribute>(property); if (property.propertyType == SerializedPropertyType.Vector2) { var controlRect = EditorGUILayout.GetControlRect(); var labelWidth = EditorGUIUtility.labelWidth; var floatFieldWidth = EditorGUIUtility.fieldWidth; var sliderWidth = controlRect.width - labelWidth - 2f * floatFieldWidth; var sliderPadding = 5f; var labelRect = new Rect( controlRect.x, controlRect.y, labelWidth, controlRect.height); var sliderRect = new Rect( controlRect.x + labelWidth + floatFieldWidth + sliderPadding, controlRect.y, sliderWidth - 2f * sliderPadding, controlRect.height); var minFloatFieldRect = new Rect( controlRect.x + labelWidth, controlRect.y, floatFieldWidth, controlRect.height); var 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(); var 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 { var warning = minMaxSliderAttribute.GetType().Name + " can be used only on Vector2 fields"; EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, PropertyUtility.GetTargetObject(property)); EditorDrawUtility.DrawPropertyField(property); } }