diff --git a/Editor/MinMaxSliderEditor.cs b/Editor/MinMaxSliderEditor.cs
new file mode 100644
index 0000000..19f6457
--- /dev/null
+++ b/Editor/MinMaxSliderEditor.cs
@@ -0,0 +1,121 @@
+///Credit brogan89
+///Sourced from - https://github.com/brogan89/MinMaxSlider
+
+using System;
+using UnityEditor;
+using UnityEditor.UI;
+
+namespace UnityEngine.UI.Extensions
+{
+ [CustomEditor(typeof(MinMaxSlider), true)]
+ [CanEditMultipleObjects]
+ public class MinMaxSliderEditor : SelectableEditor
+ {
+ private SerializedProperty _customCamera;
+ private SerializedProperty _sliderBounds;
+ private SerializedProperty _minHandle;
+ private SerializedProperty _maxHandle;
+ private SerializedProperty _minText;
+ private SerializedProperty _maxText;
+ private SerializedProperty _textFormat;
+ private SerializedProperty _middleGraphic;
+ private SerializedProperty _minLimit;
+ private SerializedProperty _maxLimit;
+ private SerializedProperty _wholeNumbers;
+ private SerializedProperty _minValue;
+ private SerializedProperty _maxValue;
+
+ private SerializedProperty _onValueChanged;
+
+ private readonly GUIContent label = new GUIContent("Min Max Values");
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ _customCamera = serializedObject.FindProperty("customCamera");
+ _sliderBounds = serializedObject.FindProperty("sliderBounds");
+ _minHandle = serializedObject.FindProperty("minHandle");
+ _maxHandle = serializedObject.FindProperty("maxHandle");
+ _minText = serializedObject.FindProperty("minText");
+ _maxText = serializedObject.FindProperty("maxText");
+ _textFormat = serializedObject.FindProperty("textFormat");
+ _middleGraphic = serializedObject.FindProperty("middleGraphic");
+ _minLimit = serializedObject.FindProperty("minLimit");
+ _maxLimit = serializedObject.FindProperty("maxLimit");
+ _wholeNumbers = serializedObject.FindProperty("wholeNumbers");
+ _minValue = serializedObject.FindProperty("minValue");
+ _maxValue = serializedObject.FindProperty("maxValue");
+ _onValueChanged = serializedObject.FindProperty("onValueChanged");
+ }
+
+ public override void OnInspectorGUI()
+ {
+ base.OnInspectorGUI();
+
+ serializedObject.Update();
+
+ float minLimitOld = _minLimit.floatValue;
+ float maxLimitOld = _maxLimit.floatValue;
+ float minValueOld = _minValue.floatValue;
+ float maxValueOld = _maxValue.floatValue;
+
+ EditorGUILayout.PropertyField(_customCamera);
+ EditorGUILayout.PropertyField(_sliderBounds);
+ EditorGUILayout.PropertyField(_minHandle);
+ EditorGUILayout.PropertyField(_maxHandle);
+ EditorGUILayout.PropertyField(_middleGraphic);
+
+ EditorGUILayout.PropertyField(_minText);
+ EditorGUILayout.PropertyField(_maxText);
+ EditorGUILayout.PropertyField(_textFormat);
+
+ EditorGUILayout.PropertyField(_minLimit);
+ EditorGUILayout.PropertyField(_maxLimit);
+
+ EditorGUILayout.PropertyField(_wholeNumbers);
+ EditorGUILayout.PropertyField(_minValue);
+ EditorGUILayout.PropertyField(_maxValue);
+
+ float minValue = Mathf.Clamp(_minValue.floatValue, _minLimit.floatValue, _maxLimit.floatValue);
+ float maxValue = Mathf.Clamp(_maxValue.floatValue, _minLimit.floatValue, _maxLimit.floatValue);
+ EditorGUILayout.MinMaxSlider(label, ref minValue, ref maxValue, _minLimit.floatValue, _maxLimit.floatValue);
+
+ bool anyValueChanged = !IsEqualFloat(minValueOld, minValue)
+ || !IsEqualFloat(maxValueOld, maxValue)
+ || !IsEqualFloat(minLimitOld, _minLimit.floatValue)
+ || !IsEqualFloat(maxLimitOld, _maxLimit.floatValue);
+
+ if (anyValueChanged)
+ {
+ MinMaxSlider slider = (MinMaxSlider)target;
+
+ // force limits to ints if whole numbers.
+ // needed to do this here because it wouldn't set in component script for some reason
+ if (slider.wholeNumbers)
+ {
+ _minLimit.floatValue = Mathf.RoundToInt(_minLimit.floatValue);
+ _maxLimit.floatValue = Mathf.RoundToInt(_maxLimit.floatValue);
+ }
+
+ // set slider values
+ slider.SetValues(minValue, maxValue, _minLimit.floatValue, _maxLimit.floatValue);
+ }
+
+ EditorGUILayout.Space();
+ EditorGUILayout.PropertyField(_onValueChanged);
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ ///
+ /// Returns true if floating point numbers are within 0.01f (close enough to be considered equal)
+ ///
+ ///
+ ///
+ ///
+ private static bool IsEqualFloat(float a, float b)
+ {
+ return Math.Abs(a - b) < 0.01f;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Editor/MinMaxSliderEditor.cs.meta b/Editor/MinMaxSliderEditor.cs.meta
new file mode 100644
index 0000000..6730b44
--- /dev/null
+++ b/Editor/MinMaxSliderEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 69352ed1561021b48ac258f81f48a988
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Editor/UIExtensionsMenuOptions.cs b/Editor/UIExtensionsMenuOptions.cs
index b445a7b..9c718c8 100644
--- a/Editor/UIExtensionsMenuOptions.cs
+++ b/Editor/UIExtensionsMenuOptions.cs
@@ -1,4 +1,5 @@
-using UnityEngine;
+using TMPro;
+using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine.UI.Extensions;
@@ -1847,7 +1848,7 @@ namespace UnityEditor.UI
#endregion
#region Stepper
- [MenuItem("GameObject/UI/Extensions/Stepper", false)]
+ [MenuItem("GameObject/UI/Extensions/Sliders/Stepper", false)]
static public void AddStepper(MenuCommand menuCommand)
{
GameObject go = CreateUIElementRoot("Stepper", menuCommand, new Vector2(kWidth / 2, kThickHeight));
@@ -1891,7 +1892,7 @@ namespace UnityEditor.UI
#endregion
#region BoxSlider
- [MenuItem("GameObject/UI/Extensions/Box Slider", false)]
+ [MenuItem("GameObject/UI/Extensions/Sliders/Box Slider", false)]
static public void AddBoxSlider(MenuCommand menuCommand)
{
@@ -1946,7 +1947,7 @@ namespace UnityEditor.UI
#endregion
#region Radial Slider
- [MenuItem("GameObject/UI/Extensions/Radial Slider", false)]
+ [MenuItem("GameObject/UI/Extensions/Sliders/Radial Slider", false)]
static public void AddRadialSlider(MenuCommand menuCommand)
{
GameObject sliderRoot = CreateUIElementRoot("Radial Slider", menuCommand, s_ThickGUIElementSize);
@@ -1984,21 +1985,21 @@ namespace UnityEditor.UI
#endregion
#region RangeSlider
- [MenuItem("GameObject/UI/Extensions/Range Slider", false)]
+ [MenuItem("GameObject/UI/Extensions/Sliders/Range Slider", false)]
static public void AddRangeSlider(MenuCommand menuCommand)
{
- GameObject rangeSliderRoot = CreateUIElementRoot("Range Slider", menuCommand, new Vector2(160, 20));
+ GameObject minMaxSliderRoot = CreateUIElementRoot("Range Slider", menuCommand, new Vector2(160, 20));
- GameObject background = CreateUIObject("Background", rangeSliderRoot);
+ GameObject background = CreateUIObject("Background", minMaxSliderRoot);
- GameObject fillArea = CreateUIObject("Fill Area", rangeSliderRoot);
+ GameObject fillArea = CreateUIObject("Fill Area", minMaxSliderRoot);
GameObject fill = CreateUIObject("Fill", fillArea);
- GameObject handleSlideArea = CreateUIObject("Handle Slide Area", rangeSliderRoot);
- GameObject lowHandle = CreateUIObject("Low Handle", handleSlideArea);
+ GameObject handleSlideArea = CreateUIObject("Handle Slide Area", minMaxSliderRoot);
+ GameObject minHandle = CreateUIObject("Low Handle", handleSlideArea);
GameObject highHandle = CreateUIObject("High Handle", handleSlideArea);
- SetAnchorsAndStretch(rangeSliderRoot);
+ SetAnchorsAndStretch(minMaxSliderRoot);
Image backgroundImage = background.AddComponent();
backgroundImage.sprite = AssetDatabase.GetBuiltinExtraResource(kBackgroundSpriteResourcePath);
backgroundImage.type = Image.Type.Sliced;
@@ -2029,8 +2030,8 @@ namespace UnityEditor.UI
handleSlideRect.offsetMin = new Vector2(10, -10);
handleSlideRect.offsetMax = new Vector2(-10, 10);
- RectTransform lowHandleRect = SetAnchorsAndStretch(lowHandle);
- Image lowHandleImage = lowHandle.AddComponent();
+ RectTransform lowHandleRect = SetAnchorsAndStretch(minHandle);
+ Image lowHandleImage = minHandle.AddComponent();
lowHandleImage.sprite = AssetDatabase.GetBuiltinExtraResource(kKnobPath);
lowHandleRect.sizeDelta = new Vector2(20, 0);
@@ -2039,7 +2040,7 @@ namespace UnityEditor.UI
highHandleImage.sprite = AssetDatabase.GetBuiltinExtraResource(kKnobPath);
highHandleRect.sizeDelta = new Vector2(20, 0);
- RangeSlider rangeSlider = rangeSliderRoot.AddComponent();
+ RangeSlider rangeSlider = minMaxSliderRoot.AddComponent();
rangeSlider.FillRect = fillRect;
rangeSlider.LowHandleRect = lowHandleRect;
rangeSlider.HighHandleRect = highHandleRect;
@@ -2047,7 +2048,7 @@ namespace UnityEditor.UI
rangeSlider.HighValue = rangeSlider.MaxValue;
rangeSlider.targetGraphic = fillImage;
- Selection.activeGameObject = rangeSliderRoot;
+ Selection.activeGameObject = minMaxSliderRoot;
}
#endregion
@@ -2062,6 +2063,80 @@ namespace UnityEditor.UI
}
#endregion
+ #region MinMaxSlider
+ [MenuItem("GameObject/UI/Extensions/Sliders/MinMax Slider", false)]
+ static public void AddMinMaxSlider(MenuCommand menuCommand)
+ {
+ GameObject minMaxSliderRoot = CreateUIElementRoot("MinMax Slider", menuCommand, new Vector2(390, 60));
+
+ //GameObject background = CreateUIObject("Background", rangeSliderRoot);
+
+ GameObject sliderBounds = CreateUIObject("Slider Bounds", minMaxSliderRoot);
+ GameObject middleGraphic = CreateUIObject("Middle Graphic", minMaxSliderRoot);
+
+ GameObject minHandle = CreateUIObject("Min Handle", minMaxSliderRoot);
+ GameObject minHandleText = CreateUIObject("Min Text", minHandle);
+ GameObject maxHandle = CreateUIObject("Max Handle", minMaxSliderRoot);
+ GameObject maxHandleText = CreateUIObject("Max Text", maxHandle);
+
+ SetAnchorsAndStretch(minMaxSliderRoot);
+ Image backgroundImage = minMaxSliderRoot.AddComponent();
+ backgroundImage.sprite = AssetDatabase.GetBuiltinExtraResource(kStandardSpritePath);
+ backgroundImage.type = Image.Type.Sliced;
+ backgroundImage.fillCenter = false;
+ backgroundImage.color = new Color(27, 41, 89);
+
+ RectTransform backgroundRect = backgroundImage.rectTransform;
+ backgroundRect.anchorMin = new Vector2(0.5f, 0.5f);
+ backgroundRect.anchorMax = new Vector2(0.5f, 0.5f);
+ backgroundRect.sizeDelta = Vector2.zero;
+
+ RectTransform sliderBoundsRect = SetAnchorsAndStretch(sliderBounds);
+ sliderBoundsRect.anchorMin = new Vector2(0, 0);
+ sliderBoundsRect.anchorMax = new Vector2(1, 1);
+
+ RectTransform middleGraphicRect = SetAnchorsAndStretch(middleGraphic);
+ Image fillImage = middleGraphic.AddComponent();
+ fillImage.sprite = AssetDatabase.GetBuiltinExtraResource(kStandardSpritePath);
+ fillImage.type = Image.Type.Sliced;
+ fillImage.fillCenter = true;
+ fillImage.color = new Color(41, 98, 164);
+
+ RectTransform minHandleRect = SetAnchorsAndStretch(minHandle);
+ Image lowHandleImage = minHandle.AddComponent();
+ lowHandleImage.sprite = AssetDatabase.GetBuiltinExtraResource(kStandardSpritePath);
+ minHandleRect.sizeDelta = new Vector2(30, 62);
+
+ RectTransform minHandleTextRect = SetAnchorsAndStretch(minHandleText);
+ TextMeshProUGUI minHandleTextComponent = minHandleText.AddComponent();
+ minHandleTextComponent.text = "0";
+ minHandleTextComponent.fontSize = 36;
+ minHandleTextRect.sizeDelta = new Vector2(70, 50);
+ minHandleTextRect.position = new Vector3(0, -60,0);
+
+ RectTransform maxHandleRect = SetAnchorsAndStretch(maxHandle);
+ Image maxHandleImage = maxHandle.AddComponent();
+ maxHandleImage.sprite = AssetDatabase.GetBuiltinExtraResource(kStandardSpritePath);
+ maxHandleRect.sizeDelta = new Vector2(20, 0);
+
+ RectTransform maxHandleTextRect = SetAnchorsAndStretch(maxHandleText);
+ TextMeshProUGUI maxHandleTextComponent = maxHandleText.AddComponent();
+ maxHandleTextComponent.text = "0";
+ maxHandleTextComponent.fontSize = 36;
+ maxHandleTextRect.sizeDelta = new Vector2(70, 50);
+ maxHandleTextRect.position = new Vector3(0, -60, 0);
+
+ MinMaxSlider minMaxSlider = minMaxSliderRoot.AddComponent();
+ minMaxSlider.SliderBounds = sliderBoundsRect;
+ minMaxSlider.MinHandle = minHandleRect;
+ minMaxSlider.MaxHandle = maxHandleRect;
+ minMaxSlider.MiddleGraphic = middleGraphicRect;
+ minMaxSlider.MinText = minHandleTextComponent;
+ minMaxSlider.MaxText = maxHandleTextComponent;
+
+ Selection.activeGameObject = minMaxSliderRoot;
+ }
+ #endregion
#endregion
diff --git a/Editor/UnityUIExtensions.Editor.asmdef b/Editor/UnityUIExtensions.Editor.asmdef
index a6ccce7..568a7e8 100644
--- a/Editor/UnityUIExtensions.Editor.asmdef
+++ b/Editor/UnityUIExtensions.Editor.asmdef
@@ -1,9 +1,11 @@
{
"name": "UnityUIExtensions.editor",
+ "rootNamespace": "",
"references": [
"GUID:343deaaf83e0cee4ca978e7df0b80d21",
"GUID:2bafac87e7f4b9b418d9448d219b01ab",
- "GUID:cf414061cae3a954baf92763590f3127"
+ "GUID:cf414061cae3a954baf92763590f3127",
+ "GUID:6055be8ebefd69e48b49212b09b47b2f"
],
"includePlatforms": [
"Editor"
@@ -14,5 +16,6 @@
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
- "versionDefines": []
+ "versionDefines": [],
+ "noEngineReferences": false
}
\ No newline at end of file
diff --git a/Runtime/Scripts/Controls/Sliders.meta b/Runtime/Scripts/Controls/Sliders.meta
new file mode 100644
index 0000000..6ae79ac
--- /dev/null
+++ b/Runtime/Scripts/Controls/Sliders.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: d7bdc7e70331fe24aba2c9549f84c657
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/Scripts/Controls/BoxSlider.cs b/Runtime/Scripts/Controls/Sliders/BoxSlider.cs
similarity index 96%
rename from Runtime/Scripts/Controls/BoxSlider.cs
rename to Runtime/Scripts/Controls/Sliders/BoxSlider.cs
index dca4608..9360300 100644
--- a/Runtime/Scripts/Controls/BoxSlider.cs
+++ b/Runtime/Scripts/Controls/Sliders/BoxSlider.cs
@@ -1,371 +1,371 @@
-///Credit judah4
-///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
-
-using System;
-using UnityEngine.Events;
-using UnityEngine.EventSystems;
-
-namespace UnityEngine.UI.Extensions
-{
- [RequireComponent(typeof(RectTransform))]
- [AddComponentMenu("UI/Extensions/BoxSlider")]
- public class BoxSlider : Selectable, IDragHandler, IInitializePotentialDragHandler, ICanvasElement
- {
- public enum Direction
- {
- LeftToRight,
- RightToLeft,
- BottomToTop,
- TopToBottom,
- }
-
- [Serializable]
- public class BoxSliderEvent : UnityEvent { }
-
- [SerializeField]
- private RectTransform m_HandleRect;
- public RectTransform HandleRect { get { return m_HandleRect; } set { if (SetClass(ref m_HandleRect, value)) { UpdateCachedReferences(); UpdateVisuals(); } } }
-
- [Space(6)]
-
- [SerializeField]
- private float m_MinValue = 0;
- public float MinValue { get { return m_MinValue; } set { if (SetStruct(ref m_MinValue, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
-
- [SerializeField]
- private float m_MaxValue = 1;
- public float MaxValue { get { return m_MaxValue; } set { if (SetStruct(ref m_MaxValue, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
-
- [SerializeField]
- private bool m_WholeNumbers = false;
- public bool WholeNumbers { get { return m_WholeNumbers; } set { if (SetStruct(ref m_WholeNumbers, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
-
- [SerializeField]
- private float m_ValueX = 1f;
- public float ValueX
- {
- get
- {
- if (WholeNumbers)
- return Mathf.Round(m_ValueX);
- return m_ValueX;
- }
- set
- {
- SetX(value);
- }
- }
-
- public float NormalizedValueX
- {
- get
- {
- if (Mathf.Approximately(MinValue, MaxValue))
- return 0;
- return Mathf.InverseLerp(MinValue, MaxValue, ValueX);
- }
- set
- {
- this.ValueX = Mathf.Lerp(MinValue, MaxValue, value);
- }
- }
-
- [SerializeField]
- private float m_ValueY = 1f;
- public float ValueY
- {
- get
- {
- if (WholeNumbers)
- return Mathf.Round(m_ValueY);
- return m_ValueY;
- }
- set
- {
- SetY(value);
- }
- }
-
- public float NormalizedValueY
- {
- get
- {
- if (Mathf.Approximately(MinValue, MaxValue))
- return 0;
- return Mathf.InverseLerp(MinValue, MaxValue, ValueY);
- }
- set
- {
- this.ValueY = Mathf.Lerp(MinValue, MaxValue, value);
- }
- }
-
- [Space(6)]
-
- // Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers.
- [SerializeField]
- private BoxSliderEvent m_OnValueChanged = new BoxSliderEvent();
- public BoxSliderEvent OnValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } }
-
- // Private fields
-
- private Transform m_HandleTransform;
- private RectTransform m_HandleContainerRect;
-
- // The offset from handle position to mouse down position
- private Vector2 m_Offset = Vector2.zero;
-
- private DrivenRectTransformTracker m_Tracker;
-
- // Size of each step.
- float StepSize { get { return WholeNumbers ? 1 : (MaxValue - MinValue) * 0.1f; } }
-
- protected BoxSlider()
- { }
-
-#if UNITY_EDITOR
- protected override void OnValidate()
- {
- base.OnValidate();
-
- if (WholeNumbers)
- {
- m_MinValue = Mathf.Round(m_MinValue);
- m_MaxValue = Mathf.Round(m_MaxValue);
- }
- UpdateCachedReferences();
- SetX(m_ValueX, false);
- SetY(m_ValueY, false);
- // Update rects since other things might affect them even if value didn't change.
- if(!Application.isPlaying) UpdateVisuals();
-
-#if UNITY_2018_3_OR_NEWER
- if (!Application.isPlaying)
-#else
- var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this);
- if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying)
-#endif
- {
- CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
- }
- }
-
-#endif // if UNITY_EDITOR
-
- public virtual void Rebuild(CanvasUpdate executing)
- {
-#if UNITY_EDITOR
- if (executing == CanvasUpdate.Prelayout)
- OnValueChanged.Invoke(ValueX, ValueY);
-#endif
- }
-
- public void LayoutComplete()
- {
-
- }
-
- public void GraphicUpdateComplete()
- {
-
- }
-
- public static bool SetClass(ref T currentValue, T newValue) where T : class
- {
- if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
- return false;
-
- currentValue = newValue;
- return true;
- }
-
- public static bool SetStruct(ref T currentValue, T newValue) where T : struct
- {
- if (currentValue.Equals(newValue))
- return false;
-
- currentValue = newValue;
- return true;
- }
-
- protected override void OnEnable()
- {
- base.OnEnable();
- UpdateCachedReferences();
- SetX(m_ValueX, false);
- SetY(m_ValueY, false);
- // Update rects since they need to be initialized correctly.
- UpdateVisuals();
- }
-
- protected override void OnDisable()
- {
- m_Tracker.Clear();
- base.OnDisable();
- }
-
- void UpdateCachedReferences()
- {
-
- if (m_HandleRect)
- {
- m_HandleTransform = m_HandleRect.transform;
- if (m_HandleTransform.parent != null)
- m_HandleContainerRect = m_HandleTransform.parent.GetComponent();
- }
- else
- {
- m_HandleContainerRect = null;
- }
- }
-
- // Set the valueUpdate the visible Image.
- void SetX(float input)
- {
- SetX(input, true);
- }
-
- void SetX(float input, bool sendCallback)
- {
- // Clamp the input
- float newValue = Mathf.Clamp(input, MinValue, MaxValue);
- if (WholeNumbers)
- newValue = Mathf.Round(newValue);
-
- // If the stepped value doesn't match the last one, it's time to update
- if (m_ValueX == newValue)
- return;
-
- m_ValueX = newValue;
- UpdateVisuals();
- if (sendCallback)
- m_OnValueChanged.Invoke(newValue, ValueY);
- }
-
- void SetY(float input)
- {
- SetY(input, true);
- }
-
- void SetY(float input, bool sendCallback)
- {
- // Clamp the input
- float newValue = Mathf.Clamp(input, MinValue, MaxValue);
- if (WholeNumbers)
- newValue = Mathf.Round(newValue);
-
- // If the stepped value doesn't match the last one, it's time to update
- if (m_ValueY == newValue)
- return;
-
- m_ValueY = newValue;
- UpdateVisuals();
- if (sendCallback)
- m_OnValueChanged.Invoke(ValueX, newValue);
- }
-
-
- protected override void OnRectTransformDimensionsChange()
- {
- base.OnRectTransformDimensionsChange();
- UpdateVisuals();
- }
-
- enum Axis
- {
- Horizontal = 0,
- Vertical = 1
- }
-
-
- // Force-update the slider. Useful if you've changed the properties and want it to update visually.
- private void UpdateVisuals()
- {
-#if UNITY_EDITOR
- if (!Application.isPlaying)
- UpdateCachedReferences();
-#endif
-
- m_Tracker.Clear();
-
-
- //to business!
- if (m_HandleContainerRect != null)
- {
- m_Tracker.Add(this, m_HandleRect, DrivenTransformProperties.Anchors);
- Vector2 anchorMin = Vector2.zero;
- Vector2 anchorMax = Vector2.one;
- anchorMin[0] = anchorMax[0] = (NormalizedValueX);
- anchorMin[1] = anchorMax[1] = (NormalizedValueY);
-
- if (Application.isPlaying)
- {
- m_HandleRect.anchorMin = anchorMin;
- m_HandleRect.anchorMax = anchorMax;
- }
-
- }
- }
-
- // Update the slider's position based on the mouse.
- void UpdateDrag(PointerEventData eventData, Camera cam)
- {
- RectTransform clickRect = m_HandleContainerRect;
- if (clickRect != null && clickRect.rect.size[0] > 0)
- {
- Vector2 localCursor;
- if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(clickRect, eventData.position, cam, out localCursor))
- return;
- localCursor -= clickRect.rect.position;
-
- float val = Mathf.Clamp01((localCursor - m_Offset)[0] / clickRect.rect.size[0]);
- NormalizedValueX = (val);
-
- float valY = Mathf.Clamp01((localCursor - m_Offset)[1] / clickRect.rect.size[1]);
- NormalizedValueY = (valY);
-
- }
- }
-
- private bool CanDrag(PointerEventData eventData)
- {
- return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left;
- }
-
- public override void OnPointerDown(PointerEventData eventData)
- {
- if (!CanDrag(eventData))
- return;
-
- base.OnPointerDown(eventData);
-
- m_Offset = Vector2.zero;
- if (m_HandleContainerRect != null && RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.position, eventData.enterEventCamera))
- {
- Vector2 localMousePos;
- if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.position, eventData.pressEventCamera, out localMousePos))
- m_Offset = localMousePos;
- m_Offset.y = -m_Offset.y;
- }
- else
- {
- // Outside the slider handle - jump to this point instead
- UpdateDrag(eventData, eventData.pressEventCamera);
- }
- }
-
- public virtual void OnDrag(PointerEventData eventData)
- {
- if (!CanDrag(eventData))
- return;
-
- UpdateDrag(eventData, eventData.pressEventCamera);
- }
-
- public virtual void OnInitializePotentialDrag(PointerEventData eventData)
- {
- eventData.useDragThreshold = false;
- }
-
- }
-}
+///Credit judah4
+///Sourced from - http://forum.unity3d.com/threads/color-picker.267043/
+
+using System;
+using UnityEngine.Events;
+using UnityEngine.EventSystems;
+
+namespace UnityEngine.UI.Extensions
+{
+ [RequireComponent(typeof(RectTransform))]
+ [AddComponentMenu("UI/Extensions/Sliders/BoxSlider")]
+ public class BoxSlider : Selectable, IDragHandler, IInitializePotentialDragHandler, ICanvasElement
+ {
+ public enum Direction
+ {
+ LeftToRight,
+ RightToLeft,
+ BottomToTop,
+ TopToBottom,
+ }
+
+ [Serializable]
+ public class BoxSliderEvent : UnityEvent { }
+
+ [SerializeField]
+ private RectTransform m_HandleRect;
+ public RectTransform HandleRect { get { return m_HandleRect; } set { if (SetClass(ref m_HandleRect, value)) { UpdateCachedReferences(); UpdateVisuals(); } } }
+
+ [Space(6)]
+
+ [SerializeField]
+ private float m_MinValue = 0;
+ public float MinValue { get { return m_MinValue; } set { if (SetStruct(ref m_MinValue, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
+
+ [SerializeField]
+ private float m_MaxValue = 1;
+ public float MaxValue { get { return m_MaxValue; } set { if (SetStruct(ref m_MaxValue, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
+
+ [SerializeField]
+ private bool m_WholeNumbers = false;
+ public bool WholeNumbers { get { return m_WholeNumbers; } set { if (SetStruct(ref m_WholeNumbers, value)) { SetX(m_ValueX); SetY(m_ValueY); UpdateVisuals(); } } }
+
+ [SerializeField]
+ private float m_ValueX = 1f;
+ public float ValueX
+ {
+ get
+ {
+ if (WholeNumbers)
+ return Mathf.Round(m_ValueX);
+ return m_ValueX;
+ }
+ set
+ {
+ SetX(value);
+ }
+ }
+
+ public float NormalizedValueX
+ {
+ get
+ {
+ if (Mathf.Approximately(MinValue, MaxValue))
+ return 0;
+ return Mathf.InverseLerp(MinValue, MaxValue, ValueX);
+ }
+ set
+ {
+ this.ValueX = Mathf.Lerp(MinValue, MaxValue, value);
+ }
+ }
+
+ [SerializeField]
+ private float m_ValueY = 1f;
+ public float ValueY
+ {
+ get
+ {
+ if (WholeNumbers)
+ return Mathf.Round(m_ValueY);
+ return m_ValueY;
+ }
+ set
+ {
+ SetY(value);
+ }
+ }
+
+ public float NormalizedValueY
+ {
+ get
+ {
+ if (Mathf.Approximately(MinValue, MaxValue))
+ return 0;
+ return Mathf.InverseLerp(MinValue, MaxValue, ValueY);
+ }
+ set
+ {
+ this.ValueY = Mathf.Lerp(MinValue, MaxValue, value);
+ }
+ }
+
+ [Space(6)]
+
+ // Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers.
+ [SerializeField]
+ private BoxSliderEvent m_OnValueChanged = new BoxSliderEvent();
+ public BoxSliderEvent OnValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } }
+
+ // Private fields
+
+ private Transform m_HandleTransform;
+ private RectTransform m_HandleContainerRect;
+
+ // The offset from handle position to mouse down position
+ private Vector2 m_Offset = Vector2.zero;
+
+ private DrivenRectTransformTracker m_Tracker;
+
+ // Size of each step.
+ float StepSize { get { return WholeNumbers ? 1 : (MaxValue - MinValue) * 0.1f; } }
+
+ protected BoxSlider()
+ { }
+
+#if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ base.OnValidate();
+
+ if (WholeNumbers)
+ {
+ m_MinValue = Mathf.Round(m_MinValue);
+ m_MaxValue = Mathf.Round(m_MaxValue);
+ }
+ UpdateCachedReferences();
+ SetX(m_ValueX, false);
+ SetY(m_ValueY, false);
+ // Update rects since other things might affect them even if value didn't change.
+ if(!Application.isPlaying) UpdateVisuals();
+
+#if UNITY_2018_3_OR_NEWER
+ if (!Application.isPlaying)
+#else
+ var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this);
+ if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying)
+#endif
+ {
+ CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
+ }
+ }
+
+#endif // if UNITY_EDITOR
+
+ public virtual void Rebuild(CanvasUpdate executing)
+ {
+#if UNITY_EDITOR
+ if (executing == CanvasUpdate.Prelayout)
+ OnValueChanged.Invoke(ValueX, ValueY);
+#endif
+ }
+
+ public void LayoutComplete()
+ {
+
+ }
+
+ public void GraphicUpdateComplete()
+ {
+
+ }
+
+ public static bool SetClass(ref T currentValue, T newValue) where T : class
+ {
+ if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
+ return false;
+
+ currentValue = newValue;
+ return true;
+ }
+
+ public static bool SetStruct(ref T currentValue, T newValue) where T : struct
+ {
+ if (currentValue.Equals(newValue))
+ return false;
+
+ currentValue = newValue;
+ return true;
+ }
+
+ protected override void OnEnable()
+ {
+ base.OnEnable();
+ UpdateCachedReferences();
+ SetX(m_ValueX, false);
+ SetY(m_ValueY, false);
+ // Update rects since they need to be initialized correctly.
+ UpdateVisuals();
+ }
+
+ protected override void OnDisable()
+ {
+ m_Tracker.Clear();
+ base.OnDisable();
+ }
+
+ void UpdateCachedReferences()
+ {
+
+ if (m_HandleRect)
+ {
+ m_HandleTransform = m_HandleRect.transform;
+ if (m_HandleTransform.parent != null)
+ m_HandleContainerRect = m_HandleTransform.parent.GetComponent();
+ }
+ else
+ {
+ m_HandleContainerRect = null;
+ }
+ }
+
+ // Set the valueUpdate the visible Image.
+ void SetX(float input)
+ {
+ SetX(input, true);
+ }
+
+ void SetX(float input, bool sendCallback)
+ {
+ // Clamp the input
+ float newValue = Mathf.Clamp(input, MinValue, MaxValue);
+ if (WholeNumbers)
+ newValue = Mathf.Round(newValue);
+
+ // If the stepped value doesn't match the last one, it's time to update
+ if (m_ValueX == newValue)
+ return;
+
+ m_ValueX = newValue;
+ UpdateVisuals();
+ if (sendCallback)
+ m_OnValueChanged.Invoke(newValue, ValueY);
+ }
+
+ void SetY(float input)
+ {
+ SetY(input, true);
+ }
+
+ void SetY(float input, bool sendCallback)
+ {
+ // Clamp the input
+ float newValue = Mathf.Clamp(input, MinValue, MaxValue);
+ if (WholeNumbers)
+ newValue = Mathf.Round(newValue);
+
+ // If the stepped value doesn't match the last one, it's time to update
+ if (m_ValueY == newValue)
+ return;
+
+ m_ValueY = newValue;
+ UpdateVisuals();
+ if (sendCallback)
+ m_OnValueChanged.Invoke(ValueX, newValue);
+ }
+
+
+ protected override void OnRectTransformDimensionsChange()
+ {
+ base.OnRectTransformDimensionsChange();
+ UpdateVisuals();
+ }
+
+ enum Axis
+ {
+ Horizontal = 0,
+ Vertical = 1
+ }
+
+
+ // Force-update the slider. Useful if you've changed the properties and want it to update visually.
+ private void UpdateVisuals()
+ {
+#if UNITY_EDITOR
+ if (!Application.isPlaying)
+ UpdateCachedReferences();
+#endif
+
+ m_Tracker.Clear();
+
+
+ //to business!
+ if (m_HandleContainerRect != null)
+ {
+ m_Tracker.Add(this, m_HandleRect, DrivenTransformProperties.Anchors);
+ Vector2 anchorMin = Vector2.zero;
+ Vector2 anchorMax = Vector2.one;
+ anchorMin[0] = anchorMax[0] = (NormalizedValueX);
+ anchorMin[1] = anchorMax[1] = (NormalizedValueY);
+
+ if (Application.isPlaying)
+ {
+ m_HandleRect.anchorMin = anchorMin;
+ m_HandleRect.anchorMax = anchorMax;
+ }
+
+ }
+ }
+
+ // Update the slider's position based on the mouse.
+ void UpdateDrag(PointerEventData eventData, Camera cam)
+ {
+ RectTransform clickRect = m_HandleContainerRect;
+ if (clickRect != null && clickRect.rect.size[0] > 0)
+ {
+ Vector2 localCursor;
+ if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(clickRect, eventData.position, cam, out localCursor))
+ return;
+ localCursor -= clickRect.rect.position;
+
+ float val = Mathf.Clamp01((localCursor - m_Offset)[0] / clickRect.rect.size[0]);
+ NormalizedValueX = (val);
+
+ float valY = Mathf.Clamp01((localCursor - m_Offset)[1] / clickRect.rect.size[1]);
+ NormalizedValueY = (valY);
+
+ }
+ }
+
+ private bool CanDrag(PointerEventData eventData)
+ {
+ return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left;
+ }
+
+ public override void OnPointerDown(PointerEventData eventData)
+ {
+ if (!CanDrag(eventData))
+ return;
+
+ base.OnPointerDown(eventData);
+
+ m_Offset = Vector2.zero;
+ if (m_HandleContainerRect != null && RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.position, eventData.enterEventCamera))
+ {
+ Vector2 localMousePos;
+ if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.position, eventData.pressEventCamera, out localMousePos))
+ m_Offset = localMousePos;
+ m_Offset.y = -m_Offset.y;
+ }
+ else
+ {
+ // Outside the slider handle - jump to this point instead
+ UpdateDrag(eventData, eventData.pressEventCamera);
+ }
+ }
+
+ public virtual void OnDrag(PointerEventData eventData)
+ {
+ if (!CanDrag(eventData))
+ return;
+
+ UpdateDrag(eventData, eventData.pressEventCamera);
+ }
+
+ public virtual void OnInitializePotentialDrag(PointerEventData eventData)
+ {
+ eventData.useDragThreshold = false;
+ }
+
+ }
+}
diff --git a/Runtime/Scripts/Controls/BoxSlider.cs.meta b/Runtime/Scripts/Controls/Sliders/BoxSlider.cs.meta
similarity index 100%
rename from Runtime/Scripts/Controls/BoxSlider.cs.meta
rename to Runtime/Scripts/Controls/Sliders/BoxSlider.cs.meta
diff --git a/Runtime/Scripts/Controls/Sliders/MinMaxSlider.cs b/Runtime/Scripts/Controls/Sliders/MinMaxSlider.cs
new file mode 100644
index 0000000..0550f13
--- /dev/null
+++ b/Runtime/Scripts/Controls/Sliders/MinMaxSlider.cs
@@ -0,0 +1,347 @@
+///Credit brogan89
+///Sourced from - https://github.com/brogan89/MinMaxSlider
+
+using System;
+using TMPro;
+using UnityEngine.Events;
+using UnityEngine.EventSystems;
+
+namespace UnityEngine.UI.Extensions
+{
+ [RequireComponent(typeof(RectTransform))]
+ [AddComponentMenu("UI/Extensions/Sliders/MinMax Slider")]
+ public class MinMaxSlider : Selectable, IBeginDragHandler, IDragHandler, IEndDragHandler
+ {
+ private enum DragState
+ {
+ Both,
+ Min,
+ Max
+ }
+
+ [Header("UI Controls")]
+ [SerializeField] private Camera customCamera = null;
+ [SerializeField] private RectTransform sliderBounds = null;
+ [SerializeField] private RectTransform minHandle = null;
+ [SerializeField] private RectTransform maxHandle = null;
+ [SerializeField] private RectTransform middleGraphic = null;
+
+ // text components (optional)
+ [Header("Display Text (Optional)")]
+ [SerializeField] private TextMeshProUGUI minText = null;
+ [SerializeField] private TextMeshProUGUI maxText = null;
+ [SerializeField] private string textFormat = "0";
+
+ // values
+ [Header("Limits")]
+ [SerializeField] private float minLimit = 0;
+ [SerializeField] private float maxLimit = 100;
+
+ [Header("Values")]
+ public bool wholeNumbers;
+ [SerializeField] private float minValue = 25;
+ [SerializeField] private float maxValue = 75;
+
+ public MinMaxValues Values => new MinMaxValues(minValue, maxValue, minLimit, maxLimit);
+
+ public RectTransform SliderBounds { get => sliderBounds; set => sliderBounds = value; }
+ public RectTransform MinHandle { get => minHandle; set => minHandle = value; }
+ public RectTransform MaxHandle { get => maxHandle; set => maxHandle = value; }
+ public RectTransform MiddleGraphic { get => middleGraphic; set => middleGraphic = value; }
+ public TextMeshProUGUI MinText { get => minText; set => minText = value; }
+ public TextMeshProUGUI MaxText { get => maxText; set => maxText = value; }
+
+ ///
+ /// Event invoked when either slider value has changed
+ ///
+ /// T0 = min, T1 = max
+ ///
+ [Serializable]
+ public class SliderEvent : UnityEvent { }
+
+ public SliderEvent onValueChanged = new SliderEvent();
+
+ private Vector2 dragStartPosition;
+ private float dragStartMinValue01;
+ private float dragStartMaxValue01;
+ private DragState dragState;
+ private bool passDragEvents; // this allows drag events to be passed through to scrollers
+
+ private Camera mainCamera;
+ private Canvas parentCanvas;
+ private bool isOverlayCanvas;
+
+ protected override void Start()
+ {
+ base.Start();
+
+ if (!sliderBounds)
+ {
+ sliderBounds = transform as RectTransform;
+ }
+
+ parentCanvas = GetComponentInParent