Skip to content

Instantly share code, notes, and snippets.

@MelMacaluso
Last active July 29, 2024 22:22
Show Gist options
  • Save MelMacaluso/f2298a77ec6ff7a0af1284b117055fab to your computer and use it in GitHub Desktop.
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…
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;
@MelMacaluso
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment