Skip to content

Instantly share code, notes, and snippets.

@Steffo99
Created May 1, 2020 00:35
Show Gist options
  • Save Steffo99/55fe24f1da12809419e5add9706c55b1 to your computer and use it in GitHub Desktop.
Save Steffo99/55fe24f1da12809419e5add9706c55b1 to your computer and use it in GitHub Desktop.
Unity script for floats and int that should stay between two values, with a custom inspector
using System;
using UnityEngine;
using UnityEditor;
[Serializable]
public class ClampedFloat {
public float minimum;
public float maximum;
public float starting;
public float _current;
public delegate void TargetHitHandler(ClampedFloat sender);
public event TargetHitHandler MinimumHit;
public event TargetHitHandler MaximumHit;
public delegate void ValueChangedHandler(ClampedFloat sender, float oldValue);
public event ValueChangedHandler ValueChanged;
public float Current {
get {
return _current;
}
set {
float previous = _current;
_current = Mathf.Clamp(value, minimum, maximum);
ValueChanged?.Invoke(this, previous);
if(_current == minimum) {
MinimumHit?.Invoke(this);
}
if(_current == maximum) {
MaximumHit?.Invoke(this);
}
}
}
}
[CustomPropertyDrawer(typeof(ClampedFloat))]
public class ClampedFloatDrawer : PropertyDrawer {
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return EditorGUIUtility.singleLineHeight * 5 + 12;
}
public override void OnGUI(Rect pos, SerializedProperty property, GUIContent label) {
Rect labelRect = new Rect(pos.x, pos.y, pos.width, EditorGUIUtility.singleLineHeight);
Rect minimumRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight + 2, pos.width, EditorGUIUtility.singleLineHeight);
Rect maximumRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight * 2 + 4, pos.width, EditorGUIUtility.singleLineHeight);
Rect startingRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight * 3 + 6, pos.width, EditorGUIUtility.singleLineHeight);
Rect currentRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight * 4 + 10, pos.width, EditorGUIUtility.singleLineHeight);
EditorGUI.BeginProperty(pos, label, property);
EditorGUI.LabelField(labelRect, label);
EditorGUI.indentLevel += 1;
GUIContent minimumLabel;
if(Application.isPlaying) {
minimumLabel = new GUIContent("⚠️ Minimum", "WARNING: Changing this value won't trigger MinimumHit events!");
}
else {
minimumLabel = new GUIContent("Minimum", "The minimum value of this variable.");
}
EditorGUI.PropertyField(minimumRect, property.FindPropertyRelative("minimum"), minimumLabel);
GUIContent maximumLabel;
if(Application.isPlaying) {
maximumLabel = new GUIContent("⚠️ Maximum", "WARNING: Changing this value won't trigger MaximumHit events!");
}
else {
maximumLabel = new GUIContent("Maximum", "The starting value of this variable.");
}
EditorGUI.PropertyField(maximumRect, property.FindPropertyRelative("maximum"), maximumLabel);
GUIContent startingLabel;
if(Application.isPlaying) {
GUI.enabled = false;
startingLabel = new GUIContent("Starting", "The starting value cannot be set while the game is playing.");
}
else {
GUI.enabled = true;
startingLabel = new GUIContent("Starting", "The starting value of this variable.");
}
EditorGUI.PropertyField(startingRect, property.FindPropertyRelative("starting"), startingLabel);
GUIContent currentLabel;
if(Application.isPlaying) {
GUI.enabled = true;
currentLabel = new GUIContent("⚠️ Current", "WARNING: Changing this value won't trigger any events!");
}
else {
GUI.enabled = false;
currentLabel = new GUIContent("Current", "The current value cannot be set while the game is not playing.");
}
EditorGUI.PropertyField(currentRect, property.FindPropertyRelative("_current"), currentLabel);
GUI.enabled = true;
EditorGUI.indentLevel -= 1;
EditorGUI.EndProperty();
}
}
using System;
using UnityEngine;
using UnityEditor;
[Serializable]
public class ClampedInt {
public int minimum;
public int maximum;
public int starting;
public int _current;
public delegate void TargetHitHandler(ClampedInt sender);
public event TargetHitHandler MinimumHit;
public event TargetHitHandler MaximumHit;
public delegate void ValueChangedHandler(ClampedInt sender, int oldValue);
public event ValueChangedHandler ValueChanged;
public int Current {
get {
return _current;
}
set {
int previous = _current;
_current = Mathf.Clamp(value, minimum, maximum);
ValueChanged?.Invoke(this, previous);
if(_current == minimum) {
MinimumHit?.Invoke(this);
}
if(_current == maximum) {
MaximumHit?.Invoke(this);
}
}
}
}
[CustomPropertyDrawer(typeof(ClampedInt))]
public class ClampedIntDrawer : PropertyDrawer {
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return EditorGUIUtility.singleLineHeight * 5 + 10;
}
public override void OnGUI(Rect pos, SerializedProperty property, GUIContent label) {
Rect labelRect = new Rect(pos.x, pos.y, pos.width, EditorGUIUtility.singleLineHeight);
Rect minimumRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight + 2, pos.width, EditorGUIUtility.singleLineHeight);
Rect maximumRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight * 2 + 4, pos.width, EditorGUIUtility.singleLineHeight);
Rect startingRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight * 3 + 6, pos.width, EditorGUIUtility.singleLineHeight);
Rect currentRect = new Rect(pos.x, pos.y + EditorGUIUtility.singleLineHeight * 4 + 10, pos.width, EditorGUIUtility.singleLineHeight);
EditorGUI.BeginProperty(pos, label, property);
EditorGUI.LabelField(labelRect, label);
EditorGUI.indentLevel += 1;
GUIContent minimumLabel;
if(Application.isPlaying) {
minimumLabel = new GUIContent("⚠️ Minimum", "WARNING: Changing this value won't trigger MinimumHit events!");
}
else {
minimumLabel = new GUIContent("Minimum", "The minimum value of this variable.");
}
EditorGUI.PropertyField(minimumRect, property.FindPropertyRelative("minimum"), minimumLabel);
GUIContent maximumLabel;
if(Application.isPlaying) {
maximumLabel = new GUIContent("⚠️ Maximum", "WARNING: Changing this value won't trigger MaximumHit events!");
}
else {
maximumLabel = new GUIContent("Maximum", "The starting value of this variable.");
}
EditorGUI.PropertyField(maximumRect, property.FindPropertyRelative("maximum"), maximumLabel);
GUIContent startingLabel;
if(Application.isPlaying) {
GUI.enabled = false;
startingLabel = new GUIContent("Starting", "The starting value cannot be set while the game is playing.");
}
else {
GUI.enabled = true;
startingLabel = new GUIContent("Starting", "The starting value of this variable.");
}
EditorGUI.PropertyField(startingRect, property.FindPropertyRelative("starting"), startingLabel);
GUIContent currentLabel;
if(Application.isPlaying) {
GUI.enabled = true;
currentLabel = new GUIContent("⚠️ Current", "WARNING: Changing this value won't trigger MinimumHit and MaximumHit events!");
}
else {
GUI.enabled = false;
currentLabel = new GUIContent("Current", "The current value cannot be set while the game is not playing.");
}
EditorGUI.PropertyField(currentRect, property.FindPropertyRelative("_current"), currentLabel);
GUI.enabled = true;
EditorGUI.indentLevel -= 1;
EditorGUI.EndProperty();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment