11/// Credit Tomasz Schelenz
22/// Sourced from - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/issues/46/feature-uiknob#comment-29243988
33
4+ using System ;
45using UnityEngine . Events ;
56using UnityEngine . EventSystems ;
67
@@ -31,17 +32,21 @@ public enum Direction { CW, CCW };
3132 [ Tooltip ( "Direction of rotation CW - clockwise, CCW - counterClockwise" ) ]
3233 public Direction direction = Direction . CW ;
3334 [ HideInInspector ]
34- public float knobValue ;
35+ public float KnobValue ;
3536 [ 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" ) ]
36- public float maxValue = 0 ;
37+ public float MaxValue = 0 ;
3738 [ Tooltip ( "How many rotations knob can do, if higher than max value, the latter will limit max value" ) ]
38- public int loops = 1 ;
39+ public int Loops = 0 ;
3940 [ Tooltip ( "Clamp output value between 0 and 1, useful with loops > 1" ) ]
40- public bool clampOutput01 = false ;
41+ public bool ClampOutput01 = false ;
4142 [ Tooltip ( "snap to position?" ) ]
42- public bool snapToPosition = false ;
43+ public bool SnapToPosition = false ;
4344 [ Tooltip ( "Number of positions to snap" ) ]
44- public int snapStepsPerLoop = 10 ;
45+ public int SnapStepsPerLoop = 10 ;
46+ [ Tooltip ( "Parent touch area to extend the touch radius" ) ]
47+ public RectTransform ParentTouchMask ;
48+ [ Tooltip ( "Default background color of the touch mask. Defaults as transparent" ) ]
49+ public Color MaskBackground = new Color ( 0 , 0 , 0 , 0 ) ;
4550 [ Space ( 30 ) ]
4651 public KnobFloatValueEvent OnValueChanged ;
4752 private float _currentLoops = 0 ;
@@ -55,7 +60,48 @@ public enum Direction { CW, CCW };
5560
5661 protected override void Awake ( )
5762 {
58- _screenSpaceOverlay = GetComponentInParent < Canvas > ( ) . rootCanvas . renderMode == RenderMode . ScreenSpaceOverlay ;
63+ _screenSpaceOverlay = GetComponentInParent < Canvas > ( ) . rootCanvas . renderMode == RenderMode . ScreenSpaceOverlay ;
64+ }
65+
66+ protected override void Start ( )
67+ {
68+ CheckForParentTouchMask ( ) ;
69+ }
70+
71+ private void CheckForParentTouchMask ( )
72+ {
73+ if ( ParentTouchMask )
74+ {
75+ Image maskImage = ParentTouchMask . gameObject . GetOrAddComponent < Image > ( ) ;
76+ maskImage . color = MaskBackground ;
77+ EventTrigger trigger = ParentTouchMask . gameObject . GetOrAddComponent < EventTrigger > ( ) ;
78+ trigger . triggers . Clear ( ) ;
79+ //PointerDownEvent
80+ EventTrigger . Entry pointerDownEntry = new EventTrigger . Entry ( ) ;
81+ pointerDownEntry . eventID = EventTriggerType . PointerDown ;
82+ pointerDownEntry . callback . AddListener ( ( data ) => { OnPointerDown ( ( PointerEventData ) data ) ; } ) ;
83+ trigger . triggers . Add ( pointerDownEntry ) ;
84+ //PointerUpEvent
85+ EventTrigger . Entry pointerUpEntry = new EventTrigger . Entry ( ) ;
86+ pointerUpEntry . eventID = EventTriggerType . PointerUp ;
87+ pointerUpEntry . callback . AddListener ( ( data ) => { OnPointerUp ( ( PointerEventData ) data ) ; } ) ;
88+ trigger . triggers . Add ( pointerUpEntry ) ;
89+ //PointerEnterEvent
90+ EventTrigger . Entry pointerEnterEntry = new EventTrigger . Entry ( ) ;
91+ pointerEnterEntry . eventID = EventTriggerType . PointerEnter ;
92+ pointerEnterEntry . callback . AddListener ( ( data ) => { OnPointerEnter ( ( PointerEventData ) data ) ; } ) ;
93+ trigger . triggers . Add ( pointerEnterEntry ) ;
94+ //PointerExitEvent
95+ EventTrigger . Entry pointerExitEntry = new EventTrigger . Entry ( ) ;
96+ pointerExitEntry . eventID = EventTriggerType . PointerExit ;
97+ pointerExitEntry . callback . AddListener ( ( data ) => { OnPointerExit ( ( PointerEventData ) data ) ; } ) ;
98+ trigger . triggers . Add ( pointerExitEntry ) ;
99+ //DragEvent
100+ EventTrigger . Entry dragEntry = new EventTrigger . Entry ( ) ;
101+ dragEntry . eventID = EventTriggerType . Drag ;
102+ dragEntry . callback . AddListener ( ( data ) => { OnDrag ( ( PointerEventData ) data ) ; } ) ;
103+ trigger . triggers . Add ( dragEntry ) ;
104+ }
59105 }
60106
61107 public override void OnPointerUp ( PointerEventData eventData )
@@ -71,7 +117,6 @@ public override void OnPointerExit(PointerEventData eventData)
71117 _canDrag = false ;
72118 }
73119
74-
75120 public override void OnPointerDown ( PointerEventData eventData )
76121 {
77122 _canDrag = true ;
@@ -115,83 +160,117 @@ public void OnDrag(PointerEventData eventData)
115160
116161 if ( direction == Direction . CW )
117162 {
118- knobValue = 1 - ( finalRotation . eulerAngles . z / 360f ) ;
163+ KnobValue = 1 - ( finalRotation . eulerAngles . z / 360f ) ;
119164
120- if ( snapToPosition )
165+ if ( SnapToPosition )
121166 {
122- SnapToPosition ( ref knobValue ) ;
123- finalRotation . eulerAngles = new Vector3 ( 0 , 0 , 360 - 360 * knobValue ) ;
167+ SnapToPositionValue ( ref KnobValue ) ;
168+ finalRotation . eulerAngles = new Vector3 ( 0 , 0 , 360 - 360 * KnobValue ) ;
124169 }
125170 }
126171 else
127172 {
128- knobValue = ( finalRotation . eulerAngles . z / 360f ) ;
173+ KnobValue = ( finalRotation . eulerAngles . z / 360f ) ;
129174
130- if ( snapToPosition )
175+ if ( SnapToPosition )
131176 {
132- SnapToPosition ( ref knobValue ) ;
133- finalRotation . eulerAngles = new Vector3 ( 0 , 0 , 360 * knobValue ) ;
177+ SnapToPositionValue ( ref KnobValue ) ;
178+ finalRotation . eulerAngles = new Vector3 ( 0 , 0 , 360 * KnobValue ) ;
134179 }
135180 }
136181
182+ UpdateKnobValue ( ) ;
183+
184+ transform . rotation = finalRotation ;
185+ InvokeEvents ( KnobValue + _currentLoops ) ;
186+
187+ _previousValue = KnobValue ;
188+ }
189+
190+ private void UpdateKnobValue ( )
191+ {
137192 //PREVENT OVERROTATION
138- if ( Mathf . Abs ( knobValue - _previousValue ) > 0.5f )
193+ if ( Mathf . Abs ( KnobValue - _previousValue ) > 0.5f )
139194 {
140- if ( knobValue < 0.5f && loops > 1 && _currentLoops < loops - 1 )
195+ if ( KnobValue < 0.5f && Loops > 1 && _currentLoops < Loops - 1 )
141196 {
142197 _currentLoops ++ ;
143198 }
144- else if ( knobValue > 0.5f && _currentLoops >= 1 )
199+ else if ( KnobValue > 0.5f && _currentLoops >= 1 )
145200 {
146201 _currentLoops -- ;
147202 }
148203 else
149204 {
150- if ( knobValue > 0.5f && _currentLoops == 0 )
205+ if ( KnobValue > 0.5f && _currentLoops == 0 )
151206 {
152- knobValue = 0 ;
207+ KnobValue = 0 ;
153208 transform . localEulerAngles = Vector3 . zero ;
154- InvokeEvents ( knobValue + _currentLoops ) ;
209+ InvokeEvents ( KnobValue + _currentLoops ) ;
155210 return ;
156211 }
157- else if ( knobValue < 0.5f && _currentLoops == loops - 1 )
212+ else if ( KnobValue < 0.5f && _currentLoops == Loops - 1 )
158213 {
159- knobValue = 1 ;
214+ KnobValue = 1 ;
160215 transform . localEulerAngles = Vector3 . zero ;
161- InvokeEvents ( knobValue + _currentLoops ) ;
216+ InvokeEvents ( KnobValue + _currentLoops ) ;
162217 return ;
163218 }
164219 }
165220 }
166221
167222 //CHECK MAX VALUE
168- if ( maxValue > 0 )
223+ if ( MaxValue > 0 )
169224 {
170- if ( knobValue + _currentLoops > maxValue )
225+ if ( KnobValue + _currentLoops > MaxValue )
171226 {
172- knobValue = maxValue ;
173- float maxAngle = direction == Direction . CW ? 360f - 360f * maxValue : 360f * maxValue ;
227+ KnobValue = MaxValue ;
228+ float maxAngle = direction == Direction . CW ? 360f - 360f * MaxValue : 360f * MaxValue ;
174229 transform . localEulerAngles = new Vector3 ( 0 , 0 , maxAngle ) ;
175- InvokeEvents ( knobValue ) ;
230+ InvokeEvents ( KnobValue ) ;
176231 return ;
177232 }
178233 }
234+ }
179235
180- transform . rotation = finalRotation ;
181- InvokeEvents ( knobValue + _currentLoops ) ;
236+ public void SetKnobValue ( float value , int loops = 0 )
237+ {
238+ Quaternion newRoation = Quaternion . identity ;
239+ KnobValue = value ;
240+ _currentLoops = loops ;
241+
242+ if ( SnapToPosition )
243+ {
244+ SnapToPositionValue ( ref KnobValue ) ;
182245
183- _previousValue = knobValue ;
246+ }
247+ if ( direction == Direction . CW )
248+ {
249+ newRoation . eulerAngles = new Vector3 ( 0 , 0 , 360 - 360 * KnobValue ) ;
250+ }
251+ else
252+ {
253+ newRoation . eulerAngles = new Vector3 ( 0 , 0 , 360 * KnobValue ) ;
254+ }
255+
256+ UpdateKnobValue ( ) ;
257+
258+ transform . rotation = newRoation ;
259+ InvokeEvents ( KnobValue + _currentLoops ) ;
260+
261+ _previousValue = KnobValue ;
184262 }
185- private void SnapToPosition ( ref float knobValue )
263+
264+ private void SnapToPositionValue ( ref float knobValue )
186265 {
187- float snapStep = 1 / ( float ) snapStepsPerLoop ;
266+ float snapStep = 1 / ( float ) SnapStepsPerLoop ;
188267 float newValue = Mathf . Round ( knobValue / snapStep ) * snapStep ;
189268 knobValue = newValue ;
190269 }
191270 private void InvokeEvents ( float value )
192271 {
193- if ( clampOutput01 )
194- value /= loops ;
272+ if ( ClampOutput01 )
273+ value /= Loops ;
195274 OnValueChanged . Invoke ( value ) ;
196275 }
197276
0 commit comments