diff --git a/Editor/UIExtensionsMenuOptions.cs b/Editor/UIExtensionsMenuOptions.cs index 431c0aa..0e5e19d 100644 --- a/Editor/UIExtensionsMenuOptions.cs +++ b/Editor/UIExtensionsMenuOptions.cs @@ -1637,6 +1637,15 @@ namespace UnityEditor.UI #endregion + [MenuItem("GameObject/UI/Extensions/UI Knob", false)] + static public void AddUIKnob(MenuCommand menuCommand) + { + GameObject go = CreateUIElementRoot("UI Knob", menuCommand, s_ImageGUIElementSize); + go.AddComponent(); + go.AddComponent(); + Selection.activeGameObject = go; + } + #endregion #region Helper Functions diff --git a/Scripts/Controls.meta b/Scripts/Controls.meta new file mode 100644 index 0000000..585f2e0 --- /dev/null +++ b/Scripts/Controls.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: fab8c1b6e538fad489513f03e0418451 +folderAsset: yes +timeCreated: 1468775610 +licenseType: Pro +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Scripts/Accordion.meta b/Scripts/Controls/Accordion.meta similarity index 100% rename from Scripts/Accordion.meta rename to Scripts/Controls/Accordion.meta diff --git a/Scripts/Accordion/Accordion.cs b/Scripts/Controls/Accordion/Accordion.cs similarity index 100% rename from Scripts/Accordion/Accordion.cs rename to Scripts/Controls/Accordion/Accordion.cs diff --git a/Scripts/Accordion/Accordion.cs.meta b/Scripts/Controls/Accordion/Accordion.cs.meta similarity index 100% rename from Scripts/Accordion/Accordion.cs.meta rename to Scripts/Controls/Accordion/Accordion.cs.meta diff --git a/Scripts/Accordion/AccordionElement.cs b/Scripts/Controls/Accordion/AccordionElement.cs similarity index 100% rename from Scripts/Accordion/AccordionElement.cs rename to Scripts/Controls/Accordion/AccordionElement.cs diff --git a/Scripts/Accordion/AccordionElement.cs.meta b/Scripts/Controls/Accordion/AccordionElement.cs.meta similarity index 100% rename from Scripts/Accordion/AccordionElement.cs.meta rename to Scripts/Controls/Accordion/AccordionElement.cs.meta diff --git a/Scripts/Accordion/Tweening.meta b/Scripts/Controls/Accordion/Tweening.meta similarity index 100% rename from Scripts/Accordion/Tweening.meta rename to Scripts/Controls/Accordion/Tweening.meta diff --git a/Scripts/Accordion/Tweening/FloatTween.cs b/Scripts/Controls/Accordion/Tweening/FloatTween.cs similarity index 100% rename from Scripts/Accordion/Tweening/FloatTween.cs rename to Scripts/Controls/Accordion/Tweening/FloatTween.cs diff --git a/Scripts/Accordion/Tweening/FloatTween.cs.meta b/Scripts/Controls/Accordion/Tweening/FloatTween.cs.meta similarity index 100% rename from Scripts/Accordion/Tweening/FloatTween.cs.meta rename to Scripts/Controls/Accordion/Tweening/FloatTween.cs.meta diff --git a/Scripts/Accordion/Tweening/ITweenValue.cs b/Scripts/Controls/Accordion/Tweening/ITweenValue.cs similarity index 100% rename from Scripts/Accordion/Tweening/ITweenValue.cs rename to Scripts/Controls/Accordion/Tweening/ITweenValue.cs diff --git a/Scripts/Accordion/Tweening/ITweenValue.cs.meta b/Scripts/Controls/Accordion/Tweening/ITweenValue.cs.meta similarity index 100% rename from Scripts/Accordion/Tweening/ITweenValue.cs.meta rename to Scripts/Controls/Accordion/Tweening/ITweenValue.cs.meta diff --git a/Scripts/Accordion/Tweening/TweenRunner.cs b/Scripts/Controls/Accordion/Tweening/TweenRunner.cs similarity index 100% rename from Scripts/Accordion/Tweening/TweenRunner.cs rename to Scripts/Controls/Accordion/Tweening/TweenRunner.cs diff --git a/Scripts/Accordion/Tweening/TweenRunner.cs.meta b/Scripts/Controls/Accordion/Tweening/TweenRunner.cs.meta similarity index 100% rename from Scripts/Accordion/Tweening/TweenRunner.cs.meta rename to Scripts/Controls/Accordion/Tweening/TweenRunner.cs.meta diff --git a/Scripts/ComboBox.meta b/Scripts/Controls/ComboBox.meta similarity index 100% rename from Scripts/ComboBox.meta rename to Scripts/Controls/ComboBox.meta diff --git a/Scripts/ComboBox/AutoCompleteComboBox.cs b/Scripts/Controls/ComboBox/AutoCompleteComboBox.cs similarity index 100% rename from Scripts/ComboBox/AutoCompleteComboBox.cs rename to Scripts/Controls/ComboBox/AutoCompleteComboBox.cs diff --git a/Scripts/ComboBox/AutoCompleteComboBox.cs.meta b/Scripts/Controls/ComboBox/AutoCompleteComboBox.cs.meta similarity index 100% rename from Scripts/ComboBox/AutoCompleteComboBox.cs.meta rename to Scripts/Controls/ComboBox/AutoCompleteComboBox.cs.meta diff --git a/Scripts/ComboBox/ComboBox.cs b/Scripts/Controls/ComboBox/ComboBox.cs similarity index 100% rename from Scripts/ComboBox/ComboBox.cs rename to Scripts/Controls/ComboBox/ComboBox.cs diff --git a/Scripts/ComboBox/ComboBox.cs.meta b/Scripts/Controls/ComboBox/ComboBox.cs.meta similarity index 100% rename from Scripts/ComboBox/ComboBox.cs.meta rename to Scripts/Controls/ComboBox/ComboBox.cs.meta diff --git a/Scripts/ComboBox/DropDownList.cs b/Scripts/Controls/ComboBox/DropDownList.cs similarity index 100% rename from Scripts/ComboBox/DropDownList.cs rename to Scripts/Controls/ComboBox/DropDownList.cs diff --git a/Scripts/ComboBox/DropDownList.cs.meta b/Scripts/Controls/ComboBox/DropDownList.cs.meta similarity index 100% rename from Scripts/ComboBox/DropDownList.cs.meta rename to Scripts/Controls/ComboBox/DropDownList.cs.meta diff --git a/Scripts/ComboBox/DropDownListButton.cs b/Scripts/Controls/ComboBox/DropDownListButton.cs similarity index 100% rename from Scripts/ComboBox/DropDownListButton.cs rename to Scripts/Controls/ComboBox/DropDownListButton.cs diff --git a/Scripts/ComboBox/DropDownListButton.cs.meta b/Scripts/Controls/ComboBox/DropDownListButton.cs.meta similarity index 100% rename from Scripts/ComboBox/DropDownListButton.cs.meta rename to Scripts/Controls/ComboBox/DropDownListButton.cs.meta diff --git a/Scripts/ComboBox/DropDownListItem.cs b/Scripts/Controls/ComboBox/DropDownListItem.cs similarity index 100% rename from Scripts/ComboBox/DropDownListItem.cs rename to Scripts/Controls/ComboBox/DropDownListItem.cs diff --git a/Scripts/ComboBox/DropDownListItem.cs.meta b/Scripts/Controls/ComboBox/DropDownListItem.cs.meta similarity index 100% rename from Scripts/ComboBox/DropDownListItem.cs.meta rename to Scripts/Controls/ComboBox/DropDownListItem.cs.meta diff --git a/Scripts/ReorderableList.meta b/Scripts/Controls/ReorderableList.meta similarity index 100% rename from Scripts/ReorderableList.meta rename to Scripts/Controls/ReorderableList.meta diff --git a/Scripts/ReorderableList/ReorderableList.cs b/Scripts/Controls/ReorderableList/ReorderableList.cs similarity index 100% rename from Scripts/ReorderableList/ReorderableList.cs rename to Scripts/Controls/ReorderableList/ReorderableList.cs diff --git a/Scripts/ReorderableList/ReorderableList.cs.meta b/Scripts/Controls/ReorderableList/ReorderableList.cs.meta similarity index 100% rename from Scripts/ReorderableList/ReorderableList.cs.meta rename to Scripts/Controls/ReorderableList/ReorderableList.cs.meta diff --git a/Scripts/ReorderableList/ReorderableList.unity b/Scripts/Controls/ReorderableList/ReorderableList.unity similarity index 100% rename from Scripts/ReorderableList/ReorderableList.unity rename to Scripts/Controls/ReorderableList/ReorderableList.unity diff --git a/Scripts/ReorderableList/ReorderableList.unity.meta b/Scripts/Controls/ReorderableList/ReorderableList.unity.meta similarity index 100% rename from Scripts/ReorderableList/ReorderableList.unity.meta rename to Scripts/Controls/ReorderableList/ReorderableList.unity.meta diff --git a/Scripts/ReorderableList/ReorderableListContent.cs b/Scripts/Controls/ReorderableList/ReorderableListContent.cs similarity index 100% rename from Scripts/ReorderableList/ReorderableListContent.cs rename to Scripts/Controls/ReorderableList/ReorderableListContent.cs diff --git a/Scripts/ReorderableList/ReorderableListContent.cs.meta b/Scripts/Controls/ReorderableList/ReorderableListContent.cs.meta similarity index 100% rename from Scripts/ReorderableList/ReorderableListContent.cs.meta rename to Scripts/Controls/ReorderableList/ReorderableListContent.cs.meta diff --git a/Scripts/ReorderableList/ReorderableListDebug.cs b/Scripts/Controls/ReorderableList/ReorderableListDebug.cs similarity index 100% rename from Scripts/ReorderableList/ReorderableListDebug.cs rename to Scripts/Controls/ReorderableList/ReorderableListDebug.cs diff --git a/Scripts/ReorderableList/ReorderableListDebug.cs.meta b/Scripts/Controls/ReorderableList/ReorderableListDebug.cs.meta similarity index 100% rename from Scripts/ReorderableList/ReorderableListDebug.cs.meta rename to Scripts/Controls/ReorderableList/ReorderableListDebug.cs.meta diff --git a/Scripts/ReorderableList/ReorderableListElement.cs b/Scripts/Controls/ReorderableList/ReorderableListElement.cs similarity index 100% rename from Scripts/ReorderableList/ReorderableListElement.cs rename to Scripts/Controls/ReorderableList/ReorderableListElement.cs diff --git a/Scripts/ReorderableList/ReorderableListElement.cs.meta b/Scripts/Controls/ReorderableList/ReorderableListElement.cs.meta similarity index 100% rename from Scripts/ReorderableList/ReorderableListElement.cs.meta rename to Scripts/Controls/ReorderableList/ReorderableListElement.cs.meta diff --git a/Scripts/RescalingPanels.meta b/Scripts/Controls/RescalingPanels.meta similarity index 100% rename from Scripts/RescalingPanels.meta rename to Scripts/Controls/RescalingPanels.meta diff --git a/Scripts/RescalingPanels/RescaleDragPanel.cs b/Scripts/Controls/RescalingPanels/RescaleDragPanel.cs similarity index 100% rename from Scripts/RescalingPanels/RescaleDragPanel.cs rename to Scripts/Controls/RescalingPanels/RescaleDragPanel.cs diff --git a/Scripts/RescalingPanels/RescaleDragPanel.cs.meta b/Scripts/Controls/RescalingPanels/RescaleDragPanel.cs.meta similarity index 100% rename from Scripts/RescalingPanels/RescaleDragPanel.cs.meta rename to Scripts/Controls/RescalingPanels/RescaleDragPanel.cs.meta diff --git a/Scripts/RescalingPanels/RescalePanel.cs b/Scripts/Controls/RescalingPanels/RescalePanel.cs similarity index 100% rename from Scripts/RescalingPanels/RescalePanel.cs rename to Scripts/Controls/RescalingPanels/RescalePanel.cs diff --git a/Scripts/RescalingPanels/RescalePanel.cs.meta b/Scripts/Controls/RescalingPanels/RescalePanel.cs.meta similarity index 100% rename from Scripts/RescalingPanels/RescalePanel.cs.meta rename to Scripts/Controls/RescalingPanels/RescalePanel.cs.meta diff --git a/Scripts/RescalingPanels/ResizePanel.cs b/Scripts/Controls/RescalingPanels/ResizePanel.cs similarity index 100% rename from Scripts/RescalingPanels/ResizePanel.cs rename to Scripts/Controls/RescalingPanels/ResizePanel.cs diff --git a/Scripts/RescalingPanels/ResizePanel.cs.meta b/Scripts/Controls/RescalingPanels/ResizePanel.cs.meta similarity index 100% rename from Scripts/RescalingPanels/ResizePanel.cs.meta rename to Scripts/Controls/RescalingPanels/ResizePanel.cs.meta diff --git a/Scripts/SelectionBox.meta b/Scripts/Controls/SelectionBox.meta similarity index 100% rename from Scripts/SelectionBox.meta rename to Scripts/Controls/SelectionBox.meta diff --git a/Scripts/SelectionBox/ExampleSelectable.cs b/Scripts/Controls/SelectionBox/ExampleSelectable.cs similarity index 100% rename from Scripts/SelectionBox/ExampleSelectable.cs rename to Scripts/Controls/SelectionBox/ExampleSelectable.cs diff --git a/Scripts/SelectionBox/ExampleSelectable.cs.meta b/Scripts/Controls/SelectionBox/ExampleSelectable.cs.meta similarity index 100% rename from Scripts/SelectionBox/ExampleSelectable.cs.meta rename to Scripts/Controls/SelectionBox/ExampleSelectable.cs.meta diff --git a/Scripts/SelectionBox/IBoxSelectable.cs b/Scripts/Controls/SelectionBox/IBoxSelectable.cs similarity index 100% rename from Scripts/SelectionBox/IBoxSelectable.cs rename to Scripts/Controls/SelectionBox/IBoxSelectable.cs diff --git a/Scripts/SelectionBox/IBoxSelectable.cs.meta b/Scripts/Controls/SelectionBox/IBoxSelectable.cs.meta similarity index 100% rename from Scripts/SelectionBox/IBoxSelectable.cs.meta rename to Scripts/Controls/SelectionBox/IBoxSelectable.cs.meta diff --git a/Scripts/SelectionBox/Selection Box Test.unity b/Scripts/Controls/SelectionBox/Selection Box Test.unity similarity index 100% rename from Scripts/SelectionBox/Selection Box Test.unity rename to Scripts/Controls/SelectionBox/Selection Box Test.unity diff --git a/Scripts/SelectionBox/Selection Box Test.unity.meta b/Scripts/Controls/SelectionBox/Selection Box Test.unity.meta similarity index 100% rename from Scripts/SelectionBox/Selection Box Test.unity.meta rename to Scripts/Controls/SelectionBox/Selection Box Test.unity.meta diff --git a/Scripts/SelectionBox/SelectionBox.cs b/Scripts/Controls/SelectionBox/SelectionBox.cs similarity index 100% rename from Scripts/SelectionBox/SelectionBox.cs rename to Scripts/Controls/SelectionBox/SelectionBox.cs diff --git a/Scripts/SelectionBox/SelectionBox.cs.meta b/Scripts/Controls/SelectionBox/SelectionBox.cs.meta similarity index 100% rename from Scripts/SelectionBox/SelectionBox.cs.meta rename to Scripts/Controls/SelectionBox/SelectionBox.cs.meta diff --git a/Scripts/TextPic.cs b/Scripts/Controls/TextPic.cs similarity index 100% rename from Scripts/TextPic.cs rename to Scripts/Controls/TextPic.cs diff --git a/Scripts/TextPic.cs.meta b/Scripts/Controls/TextPic.cs.meta similarity index 100% rename from Scripts/TextPic.cs.meta rename to Scripts/Controls/TextPic.cs.meta diff --git a/Scripts/Controls/UI_Knob.cs b/Scripts/Controls/UI_Knob.cs new file mode 100644 index 0000000..aca65f5 --- /dev/null +++ b/Scripts/Controls/UI_Knob.cs @@ -0,0 +1,186 @@ +/// Credit Tomasz Schelenz +/// Sourced from - https://bitbucket.org/ddreaper/unity-ui-extensions/issues/46/feature-uiknob#comment-29243988 + +using UnityEngine.Events; +using UnityEngine.EventSystems; + +/// +/// KNOB controller +/// +/// Fields +/// - direction - direction of rotation CW - clockwise CCW - counter clock wise +/// - knobValue - Output value of the control +/// - maxValue - max value knob can rotate to, if higher than loops value or set to 0 - it will be ignored, and max value will be based on loops +/// - loops - how any turns around knob can do +/// - clampOutput01 - if true the output knobValue will be clamped between 0 and 1 regardless of number of loops. +/// - snapToPosition - snap to step. NOTE: max value will override the step. +/// - snapStepsPerLoop - how many snap positions are in one knob loop; +/// - OnValueChanged - event that is called every frame while rotationg knob, sends argument of knobValue +/// NOTES +/// - script works only in images rotation on Z axis; +/// - while dragging outside of control, the rotation will be cancelled +/// +/// +namespace UnityEngine.UI.Extensions +{ + [RequireComponent(typeof(Image))] + public class UI_Knob : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler + { + public enum Direction { CW, CCW }; + [Tooltip("Direction of rotation CW - clockwise, CCW - counterClockwise")] + public Direction direction = Direction.CW; + [HideInInspector] + public float knobValue; + [Tooltip("Max value of the knob, maximum RAW output value knob can reach, overrides snap step, IF set to 0 or higher than loops, max value will be set by loops")] + public float maxValue = 0; + [Tooltip("How many rotations knob can do, if higher than max value, the latter will limit max value")] + public int loops = 1; + [Tooltip("Clamp output value between 0 and 1, usefull with loops > 1")] + public bool clampOutput01 = false; + [Tooltip("snap to position?")] + public bool snapToPosition = false; + [Tooltip("Number of positions to snap")] + public int snapStepsPerLoop = 10; + [Space(30)] + public KnobFloatValueEvent OnValueChanged; + private float _currentLoops = 0; + private float _previousValue = 0; + private float _initAngle; + private float _currentAngle; + private Vector2 _currentVector; + private Quaternion _initRotation; + private bool _canDrag = false; + + //ONLY ALLOW ROTATION WITH POINTER OVER THE CONTROL + public void OnPointerDown(PointerEventData eventData) + { + _canDrag = true; + } + public void OnPointerUp(PointerEventData eventData) + { + _canDrag = false; + } + public void OnPointerEnter(PointerEventData eventData) + { + _canDrag = true; + } + public void OnPointerExit(PointerEventData eventData) + { + _canDrag = false; + } + public void OnBeginDrag(PointerEventData eventData) + { + SetInitPointerData(eventData); + } + void SetInitPointerData(PointerEventData eventData) + { + _initRotation = transform.rotation; + _currentVector = eventData.position - (Vector2)transform.position; + _initAngle = Mathf.Atan2(_currentVector.y, _currentVector.x) * Mathf.Rad2Deg; + } + public void OnDrag(PointerEventData eventData) + { + //CHECK IF CAN DRAG + if (!_canDrag) + { + SetInitPointerData(eventData); + return; + } + _currentVector = eventData.position - (Vector2)transform.position; + _currentAngle = Mathf.Atan2(_currentVector.y, _currentVector.x) * Mathf.Rad2Deg; + + Quaternion addRotation = Quaternion.AngleAxis(_currentAngle - _initAngle, this.transform.forward); + addRotation.eulerAngles = new Vector3(0, 0, addRotation.eulerAngles.z); + + Quaternion finalRotation = _initRotation * addRotation; + + if (direction == Direction.CW) + { + knobValue = 1 - (finalRotation.eulerAngles.z / 360f); + + if (snapToPosition) + { + SnapToPosition(ref knobValue); + finalRotation.eulerAngles = new Vector3(0, 0, 360 - 360 * knobValue); + } + } + else + { + knobValue = (finalRotation.eulerAngles.z / 360f); + + if (snapToPosition) + { + SnapToPosition(ref knobValue); + finalRotation.eulerAngles = new Vector3(0, 0, 360 * knobValue); + } + } + + //PREVENT OVERROTATION + if (Mathf.Abs(knobValue - _previousValue) > 0.5f) + { + if (knobValue < 0.5f && loops > 1 && _currentLoops < loops - 1) + { + _currentLoops++; + } + else if (knobValue > 0.5f && _currentLoops >= 1) + { + _currentLoops--; + } + else + { + if (knobValue > 0.5f && _currentLoops == 0) + { + knobValue = 0; + transform.localEulerAngles = Vector3.zero; + SetInitPointerData(eventData); + InvokeEvents(knobValue + _currentLoops); + return; + } + else if (knobValue < 0.5f && _currentLoops == loops - 1) + { + knobValue = 1; + transform.localEulerAngles = Vector3.zero; + SetInitPointerData(eventData); + InvokeEvents(knobValue + _currentLoops); + return; + } + } + } + + //CHECK MAX VALUE + if (maxValue > 0) + { + if (knobValue + _currentLoops > maxValue) + { + knobValue = maxValue; + float maxAngle = direction == Direction.CW ? 360f - 360f * maxValue : 360f * maxValue; + transform.localEulerAngles = new Vector3(0, 0, maxAngle); + SetInitPointerData(eventData); + InvokeEvents(knobValue); + return; + } + } + + transform.rotation = finalRotation; + InvokeEvents(knobValue + _currentLoops); + + _previousValue = knobValue; + } + private void SnapToPosition(ref float knobValue) + { + float snapStep = 1 / (float)snapStepsPerLoop; + float newValue = Mathf.Round(knobValue / snapStep) * snapStep; + knobValue = newValue; + } + private void InvokeEvents(float value) + { + if (clampOutput01) + value /= loops; + OnValueChanged.Invoke(value); + } + } + + [System.Serializable] + public class KnobFloatValueEvent : UnityEvent { } + +} \ No newline at end of file diff --git a/Scripts/Controls/UI_Knob.cs.meta b/Scripts/Controls/UI_Knob.cs.meta new file mode 100644 index 0000000..269cf19 --- /dev/null +++ b/Scripts/Controls/UI_Knob.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d41844f60d3b21840a3ce64f958bd235 +timeCreated: 1468775570 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: