Last active
July 29, 2024 22:22
-
-
Save MelMacaluso/f2298a77ec6ff7a0af1284b117055fab to your computer and use it in GitHub Desktop.
MinMaxRangeAttribute: Unity custom property drawer provides a user-friendly min-max slider for integer values in the inspector. It is useful for developers who need to set a range of values. The custom attribute and property drawer handle MinMaxInt class, ensuring that values are clamped within specified limits and displayed as a slider with edi…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEditor; | |
using UnityEngine; | |
[System.Serializable] | |
public class MinMaxInt | |
{ | |
public int Min; | |
public int Max; | |
} | |
public class MinMaxRangeAttribute : PropertyAttribute | |
{ | |
public int minLimit; | |
public int maxLimit; | |
public MinMaxRangeAttribute(int minLimit, int maxLimit) | |
{ | |
this.minLimit = minLimit; | |
this.maxLimit = maxLimit; | |
} | |
} | |
[CustomPropertyDrawer(typeof(MinMaxRangeAttribute))] | |
public class MinMaxRangeDrawer : PropertyDrawer | |
{ | |
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |
{ | |
MinMaxRangeAttribute range = (MinMaxRangeAttribute)attribute; | |
if (property.type == nameof(MinMaxInt)) | |
{ | |
SerializedProperty minProperty = property.FindPropertyRelative("Min"); | |
SerializedProperty maxProperty = property.FindPropertyRelative("Max"); | |
if (minProperty != null && maxProperty != null) | |
{ | |
int min = minProperty.intValue; | |
int max = maxProperty.intValue; | |
float minFloat = min; | |
float maxFloat = max; | |
EditorGUI.BeginChangeCheck(); | |
// Calculate rectangles | |
Rect labelRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight); | |
Rect sliderRect = new Rect(position.x, position.y + EditorGUIUtility.singleLineHeight + 2, position.width, EditorGUIUtility.singleLineHeight); | |
Rect minLabelRect = new Rect(position.x, position.y + 2 * EditorGUIUtility.singleLineHeight + 4, position.width / 2 - 10, EditorGUIUtility.singleLineHeight); | |
Rect maxLabelRect = new Rect(position.x + position.width / 2 + 10, position.y + 2 * EditorGUIUtility.singleLineHeight + 4, position.width / 2 - 10, EditorGUIUtility.singleLineHeight); | |
// Draw the label | |
EditorGUI.LabelField(labelRect, label); | |
// Draw the slider | |
EditorGUI.MinMaxSlider(sliderRect, ref minFloat, ref maxFloat, range.minLimit, range.maxLimit); | |
// Convert float back to int | |
min = Mathf.RoundToInt(minFloat); | |
max = Mathf.RoundToInt(maxFloat); | |
// Draw the min and max labels | |
min = EditorGUI.IntField(minLabelRect, "Min", min); | |
max = EditorGUI.IntField(maxLabelRect, "Max", max); | |
// Clamp values to ensure they stay within range | |
min = Mathf.Clamp(min, range.minLimit, range.maxLimit); | |
max = Mathf.Clamp(max, range.minLimit, range.maxLimit); | |
// Ensure min is not greater than max | |
if (min > max) max = min; | |
if (EditorGUI.EndChangeCheck()) | |
{ | |
minProperty.intValue = min; | |
maxProperty.intValue = max; | |
} | |
} | |
else | |
{ | |
EditorGUI.LabelField(position, label.text, "Use only with MinMaxInt"); | |
} | |
} | |
else | |
{ | |
EditorGUI.LabelField(position, label.text, "Use only with MinMaxInt"); | |
} | |
} | |
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | |
{ | |
return EditorGUIUtility.singleLineHeight * 3 + 6; | |
} | |
} | |
// Usage: | |
// [MinMaxRange(0, 15)] | |
// public MinMaxInt ivHealthRange; |
Author
MelMacaluso
commented
Jun 24, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment