2
0

UIScrollToSelectionXY.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /// Credit zero3growlithe
  2. /// sourced from: http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-2011648
  3. /// Update by xesenix - based on UIScrollToSelection centers on selected element in scrollrect which can move in XY
  4. /// you can restrict movement by locking axis on ScrollRect component
  5. /*USAGE:
  6. Simply place the script on the ScrollRect that contains the selectable children we'll be scrolling to
  7. and drag'n'drop the RectTransform of the options "container" that we'll be scrolling.*/
  8. using UnityEngine.EventSystems;
  9. namespace UnityEngine.UI.Extensions
  10. {
  11. [AddComponentMenu("UI/Extensions/UI ScrollTo Selection XY")]
  12. [RequireComponent(typeof(ScrollRect))]
  13. public class UIScrollToSelectionXY : MonoBehaviour
  14. {
  15. #region Variables
  16. // settings
  17. public float scrollSpeed = 10f;
  18. [SerializeField]
  19. private RectTransform layoutListGroup = null;
  20. // temporary variables
  21. private RectTransform targetScrollObject;
  22. private bool scrollToSelection = true;
  23. // references
  24. private RectTransform scrollWindow = null;
  25. private ScrollRect targetScrollRect = null;
  26. #endregion
  27. // Use this for initialization
  28. private void Start()
  29. {
  30. targetScrollRect = GetComponent<ScrollRect>();
  31. scrollWindow = targetScrollRect.GetComponent<RectTransform>();
  32. }
  33. // Update is called once per frame
  34. private void Update()
  35. {
  36. ScrollRectToLevelSelection();
  37. }
  38. private void ScrollRectToLevelSelection()
  39. {
  40. // FIX: if you do not do that here events can have null value
  41. var events = EventSystem.current;
  42. // check main references
  43. bool referencesAreIncorrect =
  44. (targetScrollRect == null || layoutListGroup == null || scrollWindow == null);
  45. if (referencesAreIncorrect == true)
  46. {
  47. return;
  48. }
  49. // get calculation references
  50. RectTransform selection = events.currentSelectedGameObject != null ?
  51. events.currentSelectedGameObject.GetComponent<RectTransform>() :
  52. null;
  53. if (selection != targetScrollObject)
  54. {
  55. scrollToSelection = true;
  56. }
  57. // check if scrolling is possible
  58. bool isScrollDirectionUnknown = (selection == null || scrollToSelection == false);
  59. if (isScrollDirectionUnknown == true || selection.transform.parent != layoutListGroup.transform)
  60. {
  61. return;
  62. }
  63. bool finishedX = false, finishedY = false;
  64. if (targetScrollRect.vertical)
  65. {
  66. // move the current scroll rect to correct position
  67. float selectionPos = -selection.anchoredPosition.y;
  68. float listPixelAnchor = layoutListGroup.anchoredPosition.y;
  69. // get the element offset value depending on the cursor move direction
  70. float offlimitsValue = 0;
  71. offlimitsValue = listPixelAnchor - selectionPos;
  72. // move the target scroll rect
  73. targetScrollRect.verticalNormalizedPosition += (offlimitsValue / layoutListGroup.sizeDelta.y) * Time.deltaTime * scrollSpeed;
  74. finishedY = Mathf.Abs(offlimitsValue) < 2f;
  75. }
  76. if (targetScrollRect.horizontal)
  77. {
  78. // move the current scroll rect to correct position
  79. float selectionPos = -selection.anchoredPosition.x;
  80. float listPixelAnchor = layoutListGroup.anchoredPosition.x;
  81. // get the element offset value depending on the cursor move direction
  82. float offlimitsValue = 0;
  83. offlimitsValue = listPixelAnchor - selectionPos;
  84. // move the target scroll rect
  85. targetScrollRect.horizontalNormalizedPosition += (offlimitsValue / layoutListGroup.sizeDelta.x) * Time.deltaTime * scrollSpeed;
  86. finishedX = Mathf.Abs(offlimitsValue) < 2f;
  87. }
  88. // check if we reached our destination
  89. if (finishedX && finishedY) {
  90. scrollToSelection = false;
  91. }
  92. // save last object we were "heading to" to prevent blocking
  93. targetScrollObject = selection;
  94. }
  95. }
  96. }