Tanoda
RadialSlider.cs
Go to the documentation of this file.
1
4
5using System;
8
10{
11 [AddComponentMenu("UI/Extensions/Radial Slider")]
12 [RequireComponent(typeof(Image))]
13 public class RadialSlider : MonoBehaviour, IPointerEnterHandler, IPointerDownHandler, IPointerUpHandler, IDragHandler
14 {
15 private bool isPointerDown, isPointerReleased, lerpInProgress;
16 private Vector2 m_localPos, m_screenPos;
17 private float m_targetAngle, m_lerpTargetAngle, m_startAngle, m_currentLerpTime, m_lerpTime;
18 private Camera m_eventCamera;
19 private Image m_image;
20
21 [SerializeField]
22 [Tooltip("Radial Gradient Start Color")]
23 private Color m_startColor = Color.green;
24 [SerializeField]
25 [Tooltip("Radial Gradient End Color")]
26 private Color m_endColor = Color.red;
27 [Tooltip("Move slider absolute or use Lerping?\nDragging only supported with absolute")]
28 [SerializeField]
29 private bool m_lerpToTarget;
30 [Tooltip("Curve to apply to the Lerp\nMust be set to enable Lerp")]
31 [SerializeField]
32 private AnimationCurve m_lerpCurve;
33 [Tooltip("Event fired when value of control changes, outputs an INT angle value")]
34 [SerializeField]
36 [Tooltip("Event fired when value of control changes, outputs a TEXT angle value")]
37 [SerializeField]
39
40 public float Angle
41 {
42 get { return RadialImage.fillAmount * 360f; }
43 set
44 {
45 if (LerpToTarget)
46 {
47 StartLerp(value / 360f);
48 }
49 else
50 {
51 UpdateRadialImage(value / 360f);
52 }
53 }
54 }
55
56 public float Value
57 {
58 get { return RadialImage.fillAmount; }
59 set
60 {
61 if (LerpToTarget)
62 {
63 StartLerp(value);
64 }
65 else
66 {
67 UpdateRadialImage(value);
68 }
69 }
70 }
71
73 {
74 get { return m_endColor; }
75 set { m_endColor = value; }
76 }
77
79 {
80 get { return m_startColor; }
81 set { m_startColor = value; }
82 }
83
84 public bool LerpToTarget
85 {
86 get { return m_lerpToTarget; }
87 set { m_lerpToTarget = value; }
88 }
89
90 public AnimationCurve LerpCurve
91 {
92 get { return m_lerpCurve; }
93 set { m_lerpCurve = value; m_lerpTime = LerpCurve[LerpCurve.length - 1].time; }
94 }
95
96 public bool LerpInProgress
97 {
98 get { return lerpInProgress; }
99 }
100
101 [Serializable]
102 public class RadialSliderValueChangedEvent : UnityEvent<int> { }
103 [Serializable]
104 public class RadialSliderTextValueChangedEvent : UnityEvent<string> { }
105
107 {
108 get
109 {
110 if (m_image == null)
111 {
112 m_image = GetComponent<Image>();
113 m_image.type = Image.Type.Filled;
114 m_image.fillMethod = Image.FillMethod.Radial360;
115 m_image.fillAmount = 0;
116 }
117 return m_image;
118 }
119 }
120
122 {
123 get { return _onValueChanged; }
124 set { _onValueChanged = value; }
125 }
127 {
128 get { return _onTextValueChanged; }
129 set { _onTextValueChanged = value; }
130 }
131
132 private void Awake()
133 {
134 if (LerpCurve != null && LerpCurve.length > 0)
135 {
136 m_lerpTime = LerpCurve[LerpCurve.length - 1].time;
137 }
138 else
139 {
140 m_lerpTime = 1;
141 }
142 }
143
144 private void Update()
145 {
146 if (isPointerDown)
147 {
148 m_targetAngle = GetAngleFromMousePoint();
149 if (!lerpInProgress)
150 {
151 if (!LerpToTarget)
152 {
153 UpdateRadialImage(m_targetAngle);
154
155 NotifyValueChanged();
156 }
157 else
158 {
159 if (isPointerReleased) StartLerp(m_targetAngle);
160 isPointerReleased = false;
161 }
162 }
163 }
164 if (lerpInProgress && Value != m_lerpTargetAngle)
165 {
166 m_currentLerpTime += Time.deltaTime;
167 float perc = m_currentLerpTime / m_lerpTime;
168 if (LerpCurve != null && LerpCurve.length > 0)
169 {
170 UpdateRadialImage(Mathf.Lerp(m_startAngle, m_lerpTargetAngle, LerpCurve.Evaluate(perc)));
171 }
172 else
173 {
174 UpdateRadialImage(Mathf.Lerp(m_startAngle, m_lerpTargetAngle, perc));
175 }
176 }
177 if (m_currentLerpTime >= m_lerpTime || Value == m_lerpTargetAngle)
178 {
179 lerpInProgress = false;
180 UpdateRadialImage(m_lerpTargetAngle);
181 NotifyValueChanged();
182 }
183 }
184
185 private void StartLerp(float targetAngle)
186 {
187 if (!lerpInProgress)
188 {
189 m_startAngle = Value;
190 m_lerpTargetAngle = targetAngle;
191 m_currentLerpTime = 0f;
192 lerpInProgress = true;
193 }
194 }
195
196 private float GetAngleFromMousePoint()
197 {
198 RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform, m_screenPos, m_eventCamera, out m_localPos);
199
200 // radial pos of the mouse position.
201 return (Mathf.Atan2(-m_localPos.y, m_localPos.x) * 180f / Mathf.PI + 180f) / 360f;
202 }
203
204 private void UpdateRadialImage(float targetAngle)
205 {
206 RadialImage.fillAmount = targetAngle;
207
208 RadialImage.color = Color.Lerp(m_startColor, m_endColor, targetAngle);
209 }
210
211 private void NotifyValueChanged()
212 {
213 _onValueChanged.Invoke((int)(m_targetAngle * 360f));
214 _onTextValueChanged.Invoke(((int)(m_targetAngle * 360f)).ToString());
215 }
216
217//#if UNITY_EDITOR
218
219// private void OnValidate()
220// {
221// if (LerpToTarget && LerpCurve.length < 2)
222// {
223// LerpToTarget = false;
224// Debug.LogError("You need to define a Lerp Curve to enable 'Lerp To Target'");
225// }
226// }
227//#endif
228
229 #region Interfaces
230 // Called when the pointer enters our GUI component.
231 // Start tracking the mouse
232 public void OnPointerEnter(PointerEventData eventData)
233 {
234 m_screenPos = eventData.position;
235 m_eventCamera = eventData.enterEventCamera;
236 }
237
238 public void OnPointerDown(PointerEventData eventData)
239 {
240 m_screenPos = eventData.position;
241 m_eventCamera = eventData.enterEventCamera;
242 isPointerDown = true;
243 }
244
245 public void OnPointerUp(PointerEventData eventData)
246 {
247 m_screenPos = Vector2.zero;
248 isPointerDown = false;
249 isPointerReleased = true;
250 }
251
252 public void OnDrag(PointerEventData eventData)
253 {
254 m_screenPos = eventData.position;
255 }
256 #endregion
257 }
258}
System.Drawing.Image Image
Definition: TestScript.cs:37
UnityEngine.Color Color
Definition: TestScript.cs:32
void OnPointerDown(PointerEventData eventData)
void OnPointerUp(PointerEventData eventData)
RadialSliderTextValueChangedEvent onTextValueChanged
RadialSliderValueChangedEvent onValueChanged
void OnPointerEnter(PointerEventData eventData)
void OnDrag(PointerEventData eventData)
Credit Erdener Gonenc - @PixelEnvision.