PageScrollView.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. using UnityEngine.UI;
  5. public enum PageScrollType
  6. {
  7. Horizontal,
  8. Vertical
  9. }
  10. public class PageScrollView : MonoBehaviour, IBeginDragHandler, IEndDragHandler
  11. {
  12. #region 字段
  13. protected ScrollRect rect;
  14. protected int pageCount;
  15. private RectTransform content;
  16. protected float[] pages;
  17. public float moveTime = 0.3f;
  18. private float timer = 0;
  19. private float startMovePos;
  20. protected int currentPage = 0;
  21. private bool isDraging = false;
  22. private bool isMoving = false;
  23. // 是不是开启自动滚动
  24. public bool IsAutoScroll;
  25. public float AutoScrollTime = 2;
  26. private float AutoScrollTimer = 0;
  27. public PageScrollType pageScrollType = PageScrollType.Horizontal;
  28. public float vertical;
  29. #endregion
  30. #region 事件
  31. public Action<int> OnPageChange;
  32. #endregion
  33. #region Unity回调
  34. protected virtual void Start()
  35. {
  36. Init();
  37. }
  38. protected virtual void Update()
  39. {
  40. ListenerMove();
  41. ListenerAutoScroll();
  42. vertical = rect.verticalNormalizedPosition;
  43. }
  44. public void OnEndDrag(PointerEventData eventData)
  45. {
  46. // 滚动到离得最近的一页
  47. this.ScrollToPage(CaculateMinDistancePage());
  48. isDraging = false;
  49. AutoScrollTimer = 0;
  50. }
  51. public void OnBeginDrag(PointerEventData eventData)
  52. {
  53. isDraging = true;
  54. if(gameObject.name=="Scroll View (1)")
  55. SelectView.IsViewOne = true;
  56. else
  57. SelectView.IsViewOne = false;
  58. }
  59. #endregion
  60. #region 方法
  61. public void Init() {
  62. rect = transform.GetComponent<ScrollRect>();
  63. if (rect == null)
  64. {
  65. throw new System.Exception(" 未查询到ScrollRect! ");
  66. }
  67. content = transform.Find("Viewport/Content").GetComponent<RectTransform>();
  68. pageCount = content.childCount;
  69. if (pageCount == 1)
  70. {
  71. throw new System.Exception("只有一页,不用进行分页滚动!");
  72. }
  73. pages = new float[pageCount];
  74. for (int i = 0; i < pages.Length; i++)
  75. {
  76. switch (pageScrollType)
  77. {
  78. case PageScrollType.Horizontal:
  79. pages[i] = i * (1.0f / (float)(pageCount - 1));
  80. break;
  81. case PageScrollType.Vertical:
  82. pages[i] = 1 - i * (1.0f / (float)(pageCount - 1));
  83. break;
  84. }
  85. }
  86. }
  87. // 监听移动
  88. public void ListenerMove()
  89. {
  90. if (isMoving)
  91. {
  92. timer += Time.deltaTime * (1 / moveTime);
  93. switch (pageScrollType)
  94. {
  95. case PageScrollType.Horizontal:
  96. rect.horizontalNormalizedPosition = Mathf.Lerp(startMovePos, pages[currentPage], timer);
  97. break;
  98. case PageScrollType.Vertical:
  99. rect.verticalNormalizedPosition = Mathf.Lerp(startMovePos, pages[currentPage], timer);
  100. break;
  101. }
  102. if (timer >= 1)
  103. {
  104. isMoving = false;
  105. }
  106. }
  107. }
  108. // 监听自动滚动
  109. public void ListenerAutoScroll()
  110. {
  111. if (isDraging) { return; }
  112. if (IsAutoScroll)
  113. {
  114. AutoScrollTimer += Time.deltaTime;
  115. if (AutoScrollTimer >= AutoScrollTime)
  116. {
  117. AutoScrollTimer = 0;
  118. // 滚动到下一页
  119. currentPage++;
  120. currentPage %= pageCount;
  121. ScrollToPage(currentPage);
  122. }
  123. }
  124. }
  125. public void ScrollToPage(int page)
  126. {
  127. isMoving = true;
  128. this.currentPage = page;
  129. timer = 0;
  130. switch (pageScrollType)
  131. {
  132. case PageScrollType.Horizontal:
  133. startMovePos = rect.horizontalNormalizedPosition;
  134. break;
  135. case PageScrollType.Vertical:
  136. startMovePos = rect.verticalNormalizedPosition;
  137. break;
  138. }
  139. if (OnPageChange != null)
  140. {
  141. OnPageChange(this.currentPage);
  142. }
  143. }
  144. // 计算离得最近的一页
  145. public int CaculateMinDistancePage() {
  146. int minPage = 0;
  147. // 计算出离得最近的一页
  148. for (int i = 1; i < pages.Length; i++)
  149. {
  150. switch (pageScrollType)
  151. {
  152. case PageScrollType.Horizontal:
  153. if (Mathf.Abs(pages[i] - rect.horizontalNormalizedPosition) < Mathf.Abs(pages[minPage] - rect.horizontalNormalizedPosition))
  154. {
  155. minPage = i;
  156. }
  157. break;
  158. case PageScrollType.Vertical:
  159. if (Mathf.Abs(pages[i] - rect.verticalNormalizedPosition) < Mathf.Abs(pages[minPage] - rect.verticalNormalizedPosition))
  160. {
  161. minPage = i;
  162. }
  163. break;
  164. }
  165. }
  166. return minPage;
  167. }
  168. #endregion
  169. }