Slider.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. using System;
  2. using UnityEngine.Events;
  3. using UnityEngine.EventSystems;
  4. namespace UnityEngine.UI
  5. {
  6. [AddComponentMenu("UI/Slider", 33)]
  7. [ExecuteAlways]
  8. [RequireComponent(typeof(RectTransform))]
  9. /// <summary>
  10. /// A standard slider that can be moved between a minimum and maximum value.
  11. /// </summary>
  12. /// <remarks>
  13. /// The slider component is a Selectable that controls a fill, a handle, or both. The fill, when used, spans from the minimum value to the current value while the handle, when used, follow the current value.
  14. /// The anchors of the fill and handle RectTransforms are driven by the Slider. The fill and handle can be direct children of the GameObject with the Slider, or intermediary RectTransforms can be placed in between for additional control.
  15. /// When a change to the slider value occurs, a callback is sent to any registered listeners of UI.Slider.onValueChanged.
  16. /// </remarks>
  17. public class Slider : Selectable, IDragHandler, IInitializePotentialDragHandler, ICanvasElement
  18. {
  19. /// <summary>
  20. /// Setting that indicates one of four directions.
  21. /// </summary>
  22. public enum Direction
  23. {
  24. /// <summary>
  25. /// From the left to the right
  26. /// </summary>
  27. LeftToRight,
  28. /// <summary>
  29. /// From the right to the left
  30. /// </summary>
  31. RightToLeft,
  32. /// <summary>
  33. /// From the bottom to the top.
  34. /// </summary>
  35. BottomToTop,
  36. /// <summary>
  37. /// From the top to the bottom.
  38. /// </summary>
  39. TopToBottom,
  40. }
  41. [Serializable]
  42. /// <summary>
  43. /// Event type used by the UI.Slider.
  44. /// </summary>
  45. public class SliderEvent : UnityEvent<float> {}
  46. [SerializeField]
  47. private RectTransform m_FillRect;
  48. /// <summary>
  49. /// Optional RectTransform to use as fill for the slider.
  50. /// </summary>
  51. /// <example>
  52. /// <code>
  53. /// using UnityEngine;
  54. /// using System.Collections;
  55. /// using UnityEngine.UI; // Required when Using UI elements.
  56. ///
  57. /// public class Example : MonoBehaviour
  58. /// {
  59. /// public Slider mainSlider;
  60. /// //Reference to new "RectTransform"(Child of FillArea).
  61. /// public RectTransform newFillRect;
  62. ///
  63. /// //Deactivates the old FillRect and assigns a new one.
  64. /// void Start()
  65. /// {
  66. /// mainSlider.fillRect.gameObject.SetActive(false);
  67. /// mainSlider.fillRect = newFillRect;
  68. /// }
  69. /// }
  70. /// </code>
  71. /// </example>
  72. public RectTransform fillRect { get { return m_FillRect; } set { if (SetPropertyUtility.SetClass(ref m_FillRect, value)) {UpdateCachedReferences(); UpdateVisuals(); } } }
  73. [SerializeField]
  74. private RectTransform m_HandleRect;
  75. /// <summary>
  76. /// Optional RectTransform to use as a handle for the slider.
  77. /// </summary>
  78. /// <example>
  79. /// <code>
  80. /// using UnityEngine;
  81. /// using System.Collections;
  82. /// using UnityEngine.UI; // Required when Using UI elements.
  83. ///
  84. /// public class Example : MonoBehaviour
  85. /// {
  86. /// public Slider mainSlider;
  87. /// //Reference to new "RectTransform" (Child of "Handle Slide Area").
  88. /// public RectTransform handleHighlighted;
  89. ///
  90. /// //Deactivates the old Handle, then assigns and enables the new one.
  91. /// void Start()
  92. /// {
  93. /// mainSlider.handleRect.gameObject.SetActive(false);
  94. /// mainSlider.handleRect = handleHighlighted;
  95. /// mainSlider.handleRect.gameObject.SetActive(true);
  96. /// }
  97. /// }
  98. /// </code>
  99. /// </example>
  100. public RectTransform handleRect { get { return m_HandleRect; } set { if (SetPropertyUtility.SetClass(ref m_HandleRect, value)) { UpdateCachedReferences(); UpdateVisuals(); } } }
  101. [Space]
  102. [SerializeField]
  103. private Direction m_Direction = Direction.LeftToRight;
  104. /// <summary>
  105. /// The direction of the slider, from minimum to maximum value.
  106. /// </summary>
  107. /// <example>
  108. /// <code>
  109. /// using UnityEngine;
  110. /// using System.Collections;
  111. /// using UnityEngine.UI; // Required when Using UI elements.
  112. ///
  113. /// public class Example : MonoBehaviour
  114. /// {
  115. /// public Slider mainSlider;
  116. ///
  117. /// public void Start()
  118. /// {
  119. /// //Changes the direction of the slider.
  120. /// if (mainSlider.direction == Slider.Direction.BottomToTop)
  121. /// {
  122. /// mainSlider.direction = Slider.Direction.TopToBottom;
  123. /// }
  124. /// }
  125. /// }
  126. /// </code>
  127. /// </example>
  128. public Direction direction { get { return m_Direction; } set { if (SetPropertyUtility.SetStruct(ref m_Direction, value)) UpdateVisuals(); } }
  129. [SerializeField]
  130. private float m_MinValue = 0;
  131. /// <summary>
  132. /// The minimum allowed value of the slider.
  133. /// </summary>
  134. /// <example>
  135. /// <code>
  136. /// using UnityEngine;
  137. /// using System.Collections;
  138. /// using UnityEngine.UI; // Required when Using UI elements.
  139. ///
  140. /// public class Example : MonoBehaviour
  141. /// {
  142. /// public Slider mainSlider;
  143. ///
  144. /// void Start()
  145. /// {
  146. /// // Changes the minimum value of the slider to 10;
  147. /// mainSlider.minValue = 10;
  148. /// }
  149. /// }
  150. /// </code>
  151. /// </example>
  152. public float minValue { get { return m_MinValue; } set { if (SetPropertyUtility.SetStruct(ref m_MinValue, value)) { Set(m_Value); UpdateVisuals(); } } }
  153. [SerializeField]
  154. private float m_MaxValue = 1;
  155. /// <summary>
  156. /// The maximum allowed value of the slider.
  157. /// </summary>
  158. /// <example>
  159. /// <code>
  160. /// using UnityEngine;
  161. /// using System.Collections;
  162. /// using UnityEngine.UI; // Required when Using UI elements.
  163. ///
  164. /// public class Example : MonoBehaviour
  165. /// {
  166. /// public Slider mainSlider;
  167. ///
  168. /// void Start()
  169. /// {
  170. /// // Changes the max value of the slider to 20;
  171. /// mainSlider.maxValue = 20;
  172. /// }
  173. /// }
  174. /// </code>
  175. /// </example>
  176. public float maxValue { get { return m_MaxValue; } set { if (SetPropertyUtility.SetStruct(ref m_MaxValue, value)) { Set(m_Value); UpdateVisuals(); } } }
  177. [SerializeField]
  178. private bool m_WholeNumbers = false;
  179. /// <summary>
  180. /// Should the value only be allowed to be whole numbers?
  181. /// </summary>
  182. /// <example>
  183. /// <code>
  184. /// using UnityEngine;
  185. /// using System.Collections;
  186. /// using UnityEngine.UI; // Required when Using UI elements.
  187. ///
  188. /// public class Example : MonoBehaviour
  189. /// {
  190. /// public Slider mainSlider;
  191. ///
  192. /// public void Start()
  193. /// {
  194. /// //sets the slider's value to accept whole numbers only.
  195. /// mainSlider.wholeNumbers = true;
  196. /// }
  197. /// }
  198. /// </code>
  199. /// </example>
  200. public bool wholeNumbers { get { return m_WholeNumbers; } set { if (SetPropertyUtility.SetStruct(ref m_WholeNumbers, value)) { Set(m_Value); UpdateVisuals(); } } }
  201. [SerializeField]
  202. protected float m_Value;
  203. /// <summary>
  204. /// The current value of the slider.
  205. /// </summary>
  206. /// <example>
  207. /// <code>
  208. /// using UnityEngine;
  209. /// using System.Collections;
  210. /// using UnityEngine.UI; // Required when Using UI elements.
  211. ///
  212. /// public class Example : MonoBehaviour
  213. /// {
  214. /// public Slider mainSlider;
  215. ///
  216. /// //Invoked when a submit button is clicked.
  217. /// public void SubmitSliderSetting()
  218. /// {
  219. /// //Displays the value of the slider in the console.
  220. /// Debug.Log(mainSlider.value);
  221. /// }
  222. /// }
  223. /// </code>
  224. /// </example>
  225. public virtual float value
  226. {
  227. get
  228. {
  229. return wholeNumbers ? Mathf.Round(m_Value) : m_Value;
  230. }
  231. set
  232. {
  233. Set(value);
  234. }
  235. }
  236. /// <summary>
  237. /// Set the value of the slider without invoking onValueChanged callback.
  238. /// </summary>
  239. /// <param name="input">The new value for the slider.</param>
  240. public virtual void SetValueWithoutNotify(float input)
  241. {
  242. Set(input, false);
  243. }
  244. /// <summary>
  245. /// The current value of the slider normalized into a value between 0 and 1.
  246. /// </summary>
  247. /// <example>
  248. /// <code>
  249. /// using UnityEngine;
  250. /// using System.Collections;
  251. /// using UnityEngine.UI; // Required when Using UI elements.
  252. ///
  253. /// public class Example : MonoBehaviour
  254. /// {
  255. /// public Slider mainSlider;
  256. ///
  257. /// //Set to invoke when "OnValueChanged" method is called.
  258. /// void CheckNormalisedValue()
  259. /// {
  260. /// //Displays the normalised value of the slider everytime the value changes.
  261. /// Debug.Log(mainSlider.normalizedValue);
  262. /// }
  263. /// }
  264. /// </code>
  265. /// </example>
  266. public float normalizedValue
  267. {
  268. get
  269. {
  270. if (Mathf.Approximately(minValue, maxValue))
  271. return 0;
  272. return Mathf.InverseLerp(minValue, maxValue, value);
  273. }
  274. set
  275. {
  276. this.value = Mathf.Lerp(minValue, maxValue, value);
  277. }
  278. }
  279. [Space]
  280. [SerializeField]
  281. private SliderEvent m_OnValueChanged = new SliderEvent();
  282. /// <summary>
  283. /// Callback executed when the value of the slider is changed.
  284. /// </summary>
  285. /// <example>
  286. /// <code>
  287. /// using UnityEngine;
  288. /// using System.Collections;
  289. /// using UnityEngine.UI; // Required when Using UI elements.
  290. ///
  291. /// public class Example : MonoBehaviour
  292. /// {
  293. /// public Slider mainSlider;
  294. ///
  295. /// public void Start()
  296. /// {
  297. /// //Adds a listener to the main slider and invokes a method when the value changes.
  298. /// mainSlider.onValueChanged.AddListener(delegate {ValueChangeCheck(); });
  299. /// }
  300. ///
  301. /// // Invoked when the value of the slider changes.
  302. /// public void ValueChangeCheck()
  303. /// {
  304. /// Debug.Log(mainSlider.value);
  305. /// }
  306. /// }
  307. /// </code>
  308. /// </example>
  309. public SliderEvent onValueChanged { get { return m_OnValueChanged; } set { m_OnValueChanged = value; } }
  310. // Private fields
  311. private Image m_FillImage;
  312. private Transform m_FillTransform;
  313. private RectTransform m_FillContainerRect;
  314. private Transform m_HandleTransform;
  315. private RectTransform m_HandleContainerRect;
  316. // The offset from handle position to mouse down position
  317. private Vector2 m_Offset = Vector2.zero;
  318. // field is never assigned warning
  319. #pragma warning disable 649
  320. private DrivenRectTransformTracker m_Tracker;
  321. #pragma warning restore 649
  322. // This "delayed" mechanism is required for case 1037681.
  323. private bool m_DelayedUpdateVisuals = false;
  324. // Size of each step.
  325. float stepSize { get { return wholeNumbers ? 1 : (maxValue - minValue) * 0.1f; } }
  326. protected Slider()
  327. {}
  328. #if UNITY_EDITOR
  329. protected override void OnValidate()
  330. {
  331. base.OnValidate();
  332. if (wholeNumbers)
  333. {
  334. m_MinValue = Mathf.Round(m_MinValue);
  335. m_MaxValue = Mathf.Round(m_MaxValue);
  336. }
  337. //Onvalidate is called before OnEnabled. We need to make sure not to touch any other objects before OnEnable is run.
  338. if (IsActive())
  339. {
  340. UpdateCachedReferences();
  341. // Update rects in next update since other things might affect them even if value didn't change.
  342. m_DelayedUpdateVisuals = true;
  343. }
  344. if (!UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && !Application.isPlaying)
  345. CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this);
  346. }
  347. #endif // if UNITY_EDITOR
  348. public virtual void Rebuild(CanvasUpdate executing)
  349. {
  350. #if UNITY_EDITOR
  351. if (executing == CanvasUpdate.Prelayout)
  352. onValueChanged.Invoke(value);
  353. #endif
  354. }
  355. /// <summary>
  356. /// See ICanvasElement.LayoutComplete
  357. /// </summary>
  358. public virtual void LayoutComplete()
  359. {}
  360. /// <summary>
  361. /// See ICanvasElement.GraphicUpdateComplete
  362. /// </summary>
  363. public virtual void GraphicUpdateComplete()
  364. {}
  365. protected override void OnEnable()
  366. {
  367. base.OnEnable();
  368. UpdateCachedReferences();
  369. Set(m_Value, false);
  370. // Update rects since they need to be initialized correctly.
  371. UpdateVisuals();
  372. }
  373. protected override void OnDisable()
  374. {
  375. m_Tracker.Clear();
  376. base.OnDisable();
  377. }
  378. /// <summary>
  379. /// Update the rect based on the delayed update visuals.
  380. /// Got around issue of calling sendMessage from onValidate.
  381. /// </summary>
  382. protected virtual void Update()
  383. {
  384. if (m_DelayedUpdateVisuals)
  385. {
  386. m_DelayedUpdateVisuals = false;
  387. Set(m_Value, false);
  388. UpdateVisuals();
  389. }
  390. }
  391. protected override void OnDidApplyAnimationProperties()
  392. {
  393. // Has value changed? Various elements of the slider have the old normalisedValue assigned, we can use this to perform a comparison.
  394. // We also need to ensure the value stays within min/max.
  395. m_Value = ClampValue(m_Value);
  396. float oldNormalizedValue = normalizedValue;
  397. if (m_FillContainerRect != null)
  398. {
  399. if (m_FillImage != null && m_FillImage.type == Image.Type.Filled)
  400. oldNormalizedValue = m_FillImage.fillAmount;
  401. else
  402. oldNormalizedValue = (reverseValue ? 1 - m_FillRect.anchorMin[(int)axis] : m_FillRect.anchorMax[(int)axis]);
  403. }
  404. else if (m_HandleContainerRect != null)
  405. oldNormalizedValue = (reverseValue ? 1 - m_HandleRect.anchorMin[(int)axis] : m_HandleRect.anchorMin[(int)axis]);
  406. UpdateVisuals();
  407. if (oldNormalizedValue != normalizedValue)
  408. {
  409. UISystemProfilerApi.AddMarker("Slider.value", this);
  410. onValueChanged.Invoke(m_Value);
  411. }
  412. }
  413. void UpdateCachedReferences()
  414. {
  415. if (m_FillRect && m_FillRect != (RectTransform)transform)
  416. {
  417. m_FillTransform = m_FillRect.transform;
  418. m_FillImage = m_FillRect.GetComponent<Image>();
  419. if (m_FillTransform.parent != null)
  420. m_FillContainerRect = m_FillTransform.parent.GetComponent<RectTransform>();
  421. }
  422. else
  423. {
  424. m_FillRect = null;
  425. m_FillContainerRect = null;
  426. m_FillImage = null;
  427. }
  428. if (m_HandleRect && m_HandleRect != (RectTransform)transform)
  429. {
  430. m_HandleTransform = m_HandleRect.transform;
  431. if (m_HandleTransform.parent != null)
  432. m_HandleContainerRect = m_HandleTransform.parent.GetComponent<RectTransform>();
  433. }
  434. else
  435. {
  436. m_HandleRect = null;
  437. m_HandleContainerRect = null;
  438. }
  439. }
  440. float ClampValue(float input)
  441. {
  442. float newValue = Mathf.Clamp(input, minValue, maxValue);
  443. if (wholeNumbers)
  444. newValue = Mathf.Round(newValue);
  445. return newValue;
  446. }
  447. /// <summary>
  448. /// Set the value of the slider.
  449. /// </summary>
  450. /// <param name="input">The new value for the slider.</param>
  451. /// <param name="sendCallback">If the OnValueChanged callback should be invoked.</param>
  452. /// <remarks>
  453. /// Process the input to ensure the value is between min and max value. If the input is different set the value and send the callback is required.
  454. /// </remarks>
  455. protected virtual void Set(float input, bool sendCallback = true)
  456. {
  457. // Clamp the input
  458. float newValue = ClampValue(input);
  459. // If the stepped value doesn't match the last one, it's time to update
  460. if (m_Value == newValue)
  461. return;
  462. m_Value = newValue;
  463. UpdateVisuals();
  464. if (sendCallback)
  465. {
  466. UISystemProfilerApi.AddMarker("Slider.value", this);
  467. m_OnValueChanged.Invoke(newValue);
  468. }
  469. }
  470. protected override void OnRectTransformDimensionsChange()
  471. {
  472. base.OnRectTransformDimensionsChange();
  473. //This can be invoked before OnEnabled is called. So we shouldn't be accessing other objects, before OnEnable is called.
  474. if (!IsActive())
  475. return;
  476. UpdateVisuals();
  477. }
  478. enum Axis
  479. {
  480. Horizontal = 0,
  481. Vertical = 1
  482. }
  483. Axis axis { get { return (m_Direction == Direction.LeftToRight || m_Direction == Direction.RightToLeft) ? Axis.Horizontal : Axis.Vertical; } }
  484. bool reverseValue { get { return m_Direction == Direction.RightToLeft || m_Direction == Direction.TopToBottom; } }
  485. // Force-update the slider. Useful if you've changed the properties and want it to update visually.
  486. private void UpdateVisuals()
  487. {
  488. #if UNITY_EDITOR
  489. if (!Application.isPlaying)
  490. UpdateCachedReferences();
  491. #endif
  492. m_Tracker.Clear();
  493. if (m_FillContainerRect != null)
  494. {
  495. m_Tracker.Add(this, m_FillRect, DrivenTransformProperties.Anchors);
  496. Vector2 anchorMin = Vector2.zero;
  497. Vector2 anchorMax = Vector2.one;
  498. if (m_FillImage != null && m_FillImage.type == Image.Type.Filled)
  499. {
  500. m_FillImage.fillAmount = normalizedValue;
  501. }
  502. else
  503. {
  504. if (reverseValue)
  505. anchorMin[(int)axis] = 1 - normalizedValue;
  506. else
  507. anchorMax[(int)axis] = normalizedValue;
  508. }
  509. m_FillRect.anchorMin = anchorMin;
  510. m_FillRect.anchorMax = anchorMax;
  511. }
  512. if (m_HandleContainerRect != null)
  513. {
  514. m_Tracker.Add(this, m_HandleRect, DrivenTransformProperties.Anchors);
  515. Vector2 anchorMin = Vector2.zero;
  516. Vector2 anchorMax = Vector2.one;
  517. anchorMin[(int)axis] = anchorMax[(int)axis] = (reverseValue ? (1 - normalizedValue) : normalizedValue);
  518. m_HandleRect.anchorMin = anchorMin;
  519. m_HandleRect.anchorMax = anchorMax;
  520. }
  521. }
  522. // Update the slider's position based on the mouse.
  523. void UpdateDrag(PointerEventData eventData, Camera cam)
  524. {
  525. RectTransform clickRect = m_HandleContainerRect ?? m_FillContainerRect;
  526. if (clickRect != null && clickRect.rect.size[(int)axis] > 0)
  527. {
  528. Vector2 position = Vector2.zero;
  529. if (!MultipleDisplayUtilities.GetRelativeMousePositionForDrag(eventData, ref position))
  530. return;
  531. Vector2 localCursor;
  532. if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(clickRect, position, cam, out localCursor))
  533. return;
  534. localCursor -= clickRect.rect.position;
  535. float val = Mathf.Clamp01((localCursor - m_Offset)[(int)axis] / clickRect.rect.size[(int)axis]);
  536. normalizedValue = (reverseValue ? 1f - val : val);
  537. }
  538. }
  539. private bool MayDrag(PointerEventData eventData)
  540. {
  541. return IsActive() && IsInteractable() && eventData.button == PointerEventData.InputButton.Left;
  542. }
  543. public override void OnPointerDown(PointerEventData eventData)
  544. {
  545. if (!MayDrag(eventData))
  546. return;
  547. base.OnPointerDown(eventData);
  548. m_Offset = Vector2.zero;
  549. if (m_HandleContainerRect != null && RectTransformUtility.RectangleContainsScreenPoint(m_HandleRect, eventData.pointerPressRaycast.screenPosition, eventData.enterEventCamera))
  550. {
  551. Vector2 localMousePos;
  552. if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_HandleRect, eventData.pointerPressRaycast.screenPosition, eventData.pressEventCamera, out localMousePos))
  553. m_Offset = localMousePos;
  554. }
  555. else
  556. {
  557. // Outside the slider handle - jump to this point instead
  558. UpdateDrag(eventData, eventData.pressEventCamera);
  559. }
  560. }
  561. public virtual void OnDrag(PointerEventData eventData)
  562. {
  563. if (!MayDrag(eventData))
  564. return;
  565. UpdateDrag(eventData, eventData.pressEventCamera);
  566. }
  567. public override void OnMove(AxisEventData eventData)
  568. {
  569. if (!IsActive() || !IsInteractable())
  570. {
  571. base.OnMove(eventData);
  572. return;
  573. }
  574. switch (eventData.moveDir)
  575. {
  576. case MoveDirection.Left:
  577. if (axis == Axis.Horizontal && FindSelectableOnLeft() == null)
  578. Set(reverseValue ? value + stepSize : value - stepSize);
  579. else
  580. base.OnMove(eventData);
  581. break;
  582. case MoveDirection.Right:
  583. if (axis == Axis.Horizontal && FindSelectableOnRight() == null)
  584. Set(reverseValue ? value - stepSize : value + stepSize);
  585. else
  586. base.OnMove(eventData);
  587. break;
  588. case MoveDirection.Up:
  589. if (axis == Axis.Vertical && FindSelectableOnUp() == null)
  590. Set(reverseValue ? value - stepSize : value + stepSize);
  591. else
  592. base.OnMove(eventData);
  593. break;
  594. case MoveDirection.Down:
  595. if (axis == Axis.Vertical && FindSelectableOnDown() == null)
  596. Set(reverseValue ? value + stepSize : value - stepSize);
  597. else
  598. base.OnMove(eventData);
  599. break;
  600. }
  601. }
  602. /// <summary>
  603. /// See Selectable.FindSelectableOnLeft
  604. /// </summary>
  605. public override Selectable FindSelectableOnLeft()
  606. {
  607. if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal)
  608. return null;
  609. return base.FindSelectableOnLeft();
  610. }
  611. /// <summary>
  612. /// See Selectable.FindSelectableOnRight
  613. /// </summary>
  614. public override Selectable FindSelectableOnRight()
  615. {
  616. if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Horizontal)
  617. return null;
  618. return base.FindSelectableOnRight();
  619. }
  620. /// <summary>
  621. /// See Selectable.FindSelectableOnUp
  622. /// </summary>
  623. public override Selectable FindSelectableOnUp()
  624. {
  625. if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical)
  626. return null;
  627. return base.FindSelectableOnUp();
  628. }
  629. /// <summary>
  630. /// See Selectable.FindSelectableOnDown
  631. /// </summary>
  632. public override Selectable FindSelectableOnDown()
  633. {
  634. if (navigation.mode == Navigation.Mode.Automatic && axis == Axis.Vertical)
  635. return null;
  636. return base.FindSelectableOnDown();
  637. }
  638. public virtual void OnInitializePotentialDrag(PointerEventData eventData)
  639. {
  640. eventData.useDragThreshold = false;
  641. }
  642. /// <summary>
  643. /// Sets the direction of this slider, optionally changing the layout as well.
  644. /// </summary>
  645. /// <param name="direction">The direction of the slider</param>
  646. /// <param name="includeRectLayouts">Should the layout be flipped together with the slider direction</param>
  647. /// <example>
  648. /// <code>
  649. /// using UnityEngine;
  650. /// using System.Collections;
  651. /// using UnityEngine.UI; // Required when Using UI elements.
  652. ///
  653. /// public class Example : MonoBehaviour
  654. /// {
  655. /// public Slider mainSlider;
  656. ///
  657. /// public void Start()
  658. /// {
  659. /// mainSlider.SetDirection(Slider.Direction.LeftToRight, false);
  660. /// }
  661. /// }
  662. /// </code>
  663. /// </example>
  664. public void SetDirection(Direction direction, bool includeRectLayouts)
  665. {
  666. Axis oldAxis = axis;
  667. bool oldReverse = reverseValue;
  668. this.direction = direction;
  669. if (!includeRectLayouts)
  670. return;
  671. if (axis != oldAxis)
  672. RectTransformUtility.FlipLayoutAxes(transform as RectTransform, true, true);
  673. if (reverseValue != oldReverse)
  674. RectTransformUtility.FlipLayoutOnAxis(transform as RectTransform, (int)axis, true, true);
  675. }
  676. }
  677. }