2
0

ScrollSnapBase.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. /// Credit BinaryX
  2. /// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1945602
  3. /// Updated by simonDarksideJ - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
  4. using System;
  5. using UnityEngine.Events;
  6. using UnityEngine.EventSystems;
  7. namespace UnityEngine.UI.Extensions
  8. {
  9. public class ScrollSnapBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IScrollSnap, IPointerClickHandler
  10. {
  11. internal Rect panelDimensions;
  12. internal RectTransform _screensContainer;
  13. internal bool _isVertical;
  14. internal int _screens = 1;
  15. internal float _scrollStartPosition;
  16. internal float _childSize;
  17. private float _childPos, _maskSize;
  18. internal Vector2 _childAnchorPoint;
  19. internal ScrollRect _scroll_rect;
  20. internal Vector3 _lerp_target;
  21. internal bool _lerp;
  22. internal bool _pointerDown = false;
  23. internal bool _settled = true;
  24. internal Vector3 _startPosition = new Vector3();
  25. [Tooltip("The currently active page")]
  26. internal int _currentPage;
  27. internal int _previousPage;
  28. internal int _halfNoVisibleItems;
  29. internal bool _isInfinite; // Is a UI Infinite scroller attached to the control
  30. internal int _infiniteWindow; // The infinite window the control is in
  31. internal float _infiniteOffset; // How much to offset a repositioning
  32. private int _bottomItem, _topItem;
  33. internal bool _startEventCalled = false;
  34. internal bool _endEventCalled = false;
  35. internal bool _suspendEvents = false;
  36. [Serializable]
  37. public class SelectionChangeStartEvent : UnityEvent { }
  38. [Serializable]
  39. public class SelectionPageChangedEvent : UnityEvent<int> { }
  40. [Serializable]
  41. public class SelectionChangeEndEvent : UnityEvent<int> { }
  42. [Tooltip("The screen / page to start the control on\n*Note, this is a 0 indexed array")]
  43. [SerializeField]
  44. public int StartingScreen = 0;
  45. [Tooltip("The distance between two pages based on page height, by default pages are next to each other")]
  46. [SerializeField]
  47. [Range(0, 8)]
  48. public float PageStep = 1;
  49. [Tooltip("The gameobject that contains toggles which suggest pagination. (optional)")]
  50. public GameObject Pagination;
  51. [Tooltip("Button to go to the previous page. (optional)")]
  52. public GameObject PrevButton;
  53. [Tooltip("Button to go to the next page. (optional)")]
  54. public GameObject NextButton;
  55. [Tooltip("Transition speed between pages. (optional)")]
  56. public float transitionSpeed = 7.5f;
  57. [Tooltip("Hard Swipe forces to swiping to the next / previous page (optional)")]
  58. public Boolean UseHardSwipe = false;
  59. [Tooltip("Fast Swipe makes swiping page next / previous (optional)")]
  60. public Boolean UseFastSwipe = false;
  61. [Tooltip("Swipe Delta Threshold looks at the speed of input to decide if a swipe will be initiated (optional)")]
  62. public Boolean UseSwipeDeltaThreshold = false;
  63. [Tooltip("Offset for how far a swipe has to travel to initiate a page change (optional)")]
  64. public int FastSwipeThreshold = 100;
  65. [Tooltip("Speed at which the ScrollRect will keep scrolling before slowing down and stopping (optional)")]
  66. public int SwipeVelocityThreshold = 100;
  67. [Tooltip("Threshold for swipe speed to initiate a swipe, below threshold will return to closest page (optional)")]
  68. public float SwipeDeltaThreshold = 5.0f;
  69. [Tooltip("Use time scale instead of unscaled time (optional)")]
  70. public Boolean UseTimeScale = true;
  71. [Tooltip("The visible bounds area, controls which items are visible/enabled. *Note Should use a RectMask. (optional)")]
  72. public RectTransform MaskArea;
  73. [Tooltip("Pixel size to buffer around Mask Area. (optional)")]
  74. public float MaskBuffer = 1;
  75. public int CurrentPage
  76. {
  77. get
  78. {
  79. return _currentPage;
  80. }
  81. internal set
  82. {
  83. if (_isInfinite)
  84. {
  85. //Work out which infinite window we are in
  86. float infWindow = (float)value / (float)_screensContainer.childCount;
  87. if (infWindow < 0)
  88. {
  89. _infiniteWindow = (int)(Math.Floor(infWindow));
  90. }
  91. else
  92. {
  93. _infiniteWindow = value / _screensContainer.childCount;
  94. }
  95. //Invert the value if negative and differentiate from Window 0
  96. _infiniteWindow = value < 0 ? (-_infiniteWindow) : _infiniteWindow;
  97. //Calculate the page within the child count range
  98. value = value % _screensContainer.childCount;
  99. if (value < 0)
  100. {
  101. value = _screensContainer.childCount + value;
  102. }
  103. else if (value > _screensContainer.childCount - 1)
  104. {
  105. value = value - _screensContainer.childCount;
  106. }
  107. }
  108. if ((value != _currentPage && value >= 0 && value < _screensContainer.childCount) || (value == 0 && _screensContainer.childCount == 0))
  109. {
  110. _previousPage = _currentPage;
  111. _currentPage = value;
  112. if (MaskArea) UpdateVisible();
  113. if (!_lerp) ScreenChange();
  114. OnCurrentScreenChange(_currentPage);
  115. }
  116. }
  117. }
  118. [Tooltip("By default the container will lerp to the start when enabled in the scene, this option overrides this and forces it to simply jump without lerping")]
  119. public bool JumpOnEnable = false;
  120. [Tooltip("By default the container will return to the original starting page when enabled, this option overrides this behaviour and stays on the current selection")]
  121. public bool RestartOnEnable = false;
  122. [Tooltip("(Experimental)\nBy default, child array objects will use the parent transform\nHowever you can disable this for some interesting effects")]
  123. public bool UseParentTransform = true;
  124. [Tooltip("Scroll Snap children. (optional)\nEither place objects in the scene as children OR\nPrefabs in this array, NOT BOTH")]
  125. public GameObject[] ChildObjects;
  126. [SerializeField]
  127. [Tooltip("Event fires when a user starts to change the selection")]
  128. private SelectionChangeStartEvent m_OnSelectionChangeStartEvent = new SelectionChangeStartEvent();
  129. public SelectionChangeStartEvent OnSelectionChangeStartEvent { get { return m_OnSelectionChangeStartEvent; } set { m_OnSelectionChangeStartEvent = value; } }
  130. [SerializeField]
  131. [Tooltip("Event fires as the page changes, while dragging or jumping")]
  132. private SelectionPageChangedEvent m_OnSelectionPageChangedEvent = new SelectionPageChangedEvent();
  133. public SelectionPageChangedEvent OnSelectionPageChangedEvent { get { return m_OnSelectionPageChangedEvent; } set { m_OnSelectionPageChangedEvent = value; } }
  134. [SerializeField]
  135. [Tooltip("Event fires when the page settles after a user has dragged")]
  136. private SelectionChangeEndEvent m_OnSelectionChangeEndEvent = new SelectionChangeEndEvent();
  137. public SelectionChangeEndEvent OnSelectionChangeEndEvent { get { return m_OnSelectionChangeEndEvent; } set { m_OnSelectionChangeEndEvent = value; } }
  138. // Use this for initialization
  139. void Awake()
  140. {
  141. if (_scroll_rect == null)
  142. {
  143. _scroll_rect = gameObject.GetComponent<ScrollRect>();
  144. }
  145. if (_scroll_rect.horizontalScrollbar && _scroll_rect.horizontal)
  146. {
  147. var hscroll = _scroll_rect.horizontalScrollbar.gameObject.AddComponent<ScrollSnapScrollbarHelper>();
  148. hscroll.ss = this;
  149. }
  150. if (_scroll_rect.verticalScrollbar && _scroll_rect.vertical)
  151. {
  152. var vscroll = _scroll_rect.verticalScrollbar.gameObject.AddComponent<ScrollSnapScrollbarHelper>();
  153. vscroll.ss = this;
  154. }
  155. panelDimensions = gameObject.GetComponent<RectTransform>().rect;
  156. if (StartingScreen < 0)
  157. {
  158. StartingScreen = 0;
  159. }
  160. _screensContainer = _scroll_rect.content;
  161. InitialiseChildObjects();
  162. if (NextButton)
  163. NextButton.GetComponent<Button>().onClick.AddListener(() => { NextScreen(); });
  164. if (PrevButton)
  165. PrevButton.GetComponent<Button>().onClick.AddListener(() => { PreviousScreen(); });
  166. _isInfinite = GetComponent<UI_InfiniteScroll>() != null;
  167. }
  168. internal void InitialiseChildObjects()
  169. {
  170. if (ChildObjects != null && ChildObjects.Length > 0)
  171. {
  172. if (_screensContainer.transform.childCount > 0)
  173. {
  174. Debug.LogError("ScrollRect Content has children, this is not supported when using managed Child Objects\n Either remove the ScrollRect Content children or clear the ChildObjects array");
  175. return;
  176. }
  177. InitialiseChildObjectsFromArray();
  178. if (GetComponent<UI_InfiniteScroll>() != null)
  179. {
  180. GetComponent<UI_InfiniteScroll>().Init();
  181. }
  182. }
  183. else
  184. {
  185. InitialiseChildObjectsFromScene();
  186. }
  187. }
  188. internal void InitialiseChildObjectsFromScene()
  189. {
  190. int childCount = _screensContainer.childCount;
  191. ChildObjects = new GameObject[childCount];
  192. for (int i = 0; i < childCount; i++)
  193. {
  194. ChildObjects[i] = _screensContainer.transform.GetChild(i).gameObject;
  195. if (MaskArea && ChildObjects[i].activeSelf)
  196. {
  197. ChildObjects[i].SetActive(false);
  198. }
  199. }
  200. }
  201. internal void InitialiseChildObjectsFromArray()
  202. {
  203. int childCount = ChildObjects.Length;
  204. RectTransform childRect;
  205. GameObject child;
  206. for (int i = 0; i < childCount; i++)
  207. {
  208. child = GameObject.Instantiate(ChildObjects[i]);
  209. //Optionally, use original GO transform when initialising, by default will use parent RectTransform position/rotation
  210. if (UseParentTransform)
  211. {
  212. childRect = child.GetComponent<RectTransform>();
  213. childRect.rotation = _screensContainer.rotation;
  214. childRect.localScale = _screensContainer.localScale;
  215. childRect.position = _screensContainer.position;
  216. }
  217. child.transform.SetParent(_screensContainer.transform);
  218. ChildObjects[i] = child;
  219. if (MaskArea && ChildObjects[i].activeSelf)
  220. {
  221. ChildObjects[i].SetActive(false);
  222. }
  223. }
  224. }
  225. internal void UpdateVisible()
  226. {
  227. //If there are no objects in the scene or a mask, exit
  228. if (!MaskArea || ChildObjects == null || ChildObjects.Length < 1 || _screensContainer.childCount < 1)
  229. {
  230. return;
  231. }
  232. _maskSize = _isVertical ? MaskArea.rect.height : MaskArea.rect.width;
  233. _halfNoVisibleItems = (int)Math.Round(_maskSize / (_childSize * MaskBuffer), MidpointRounding.AwayFromZero) / 2;
  234. _bottomItem = _topItem = 0;
  235. //work out how many items below the current page can be visible
  236. for (int i = _halfNoVisibleItems + 1; i > 0; i--)
  237. {
  238. _bottomItem = _currentPage - i < 0 ? 0 : i;
  239. if (_bottomItem > 0) break;
  240. }
  241. //work out how many items above the current page can be visible
  242. for (int i = _halfNoVisibleItems + 1; i > 0; i--)
  243. {
  244. _topItem = _screensContainer.childCount - _currentPage - i < 0 ? 0 : i;
  245. if (_topItem > 0) break;
  246. }
  247. //Set the active items active
  248. for (int i = CurrentPage - _bottomItem; i < CurrentPage + _topItem; i++)
  249. {
  250. try
  251. {
  252. ChildObjects[i].SetActive(true);
  253. }
  254. catch
  255. {
  256. Debug.Log("Failed to setactive child [" + i + "]");
  257. }
  258. }
  259. //Deactivate items out of visibility at the bottom of the ScrollRect Mask (only on scroll)
  260. if (_currentPage > _halfNoVisibleItems) ChildObjects[CurrentPage - _bottomItem].SetActive(false);
  261. //Deactivate items out of visibility at the top of the ScrollRect Mask (only on scroll)
  262. if (_screensContainer.childCount - _currentPage > _topItem) ChildObjects[CurrentPage + _topItem].SetActive(false);
  263. }
  264. //Function for switching screens with buttons
  265. public void NextScreen()
  266. {
  267. if (_currentPage < _screens - 1 || _isInfinite)
  268. {
  269. if (!_lerp) StartScreenChange();
  270. _lerp = true;
  271. if (_isInfinite)
  272. {
  273. CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition) + 1;
  274. }
  275. else
  276. {
  277. CurrentPage = _currentPage + 1;
  278. }
  279. GetPositionforPage(_currentPage, ref _lerp_target);
  280. ScreenChange();
  281. }
  282. }
  283. //Function for switching screens with buttons
  284. public void PreviousScreen()
  285. {
  286. if (_currentPage > 0 || _isInfinite)
  287. {
  288. if (!_lerp) StartScreenChange();
  289. _lerp = true;
  290. if (_isInfinite)
  291. {
  292. CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition) - 1;
  293. }
  294. else
  295. {
  296. CurrentPage = _currentPage - 1;
  297. }
  298. GetPositionforPage(_currentPage, ref _lerp_target);
  299. ScreenChange();
  300. }
  301. }
  302. /// <summary>
  303. /// Function for switching to a specific screen
  304. /// *Note, this is based on a 0 starting index - 0 to x
  305. /// </summary>
  306. /// <param name="screenIndex">0 starting index of page to jump to</param>
  307. /// <param name="pagination">Override the screen movement if driven from a pagination control</param>
  308. public void GoToScreen(int screenIndex, bool pagination = false)
  309. {
  310. if (screenIndex <= _screens - 1 && screenIndex >= 0)
  311. {
  312. if (!_lerp || pagination) StartScreenChange();
  313. _lerp = true;
  314. CurrentPage = screenIndex;
  315. GetPositionforPage(_currentPage, ref _lerp_target);
  316. ScreenChange();
  317. }
  318. }
  319. /// <summary>
  320. /// Gets the closest page for the current Scroll Rect container position
  321. /// </summary>
  322. /// <param name="pos">Position to test, normally the Scroll Rect container Local position</param>
  323. /// <returns>Closest Page number (zero indexed array value)</returns>
  324. internal int GetPageforPosition(Vector3 pos)
  325. {
  326. return _isVertical ?
  327. (int)Math.Round((_scrollStartPosition - pos.y) / _childSize) :
  328. (int)Math.Round((_scrollStartPosition - pos.x) / _childSize);
  329. }
  330. /// <summary>
  331. /// Validates if the current Scroll Rect container position is within the bounds for a page
  332. /// </summary>
  333. /// <param name="pos">Position to test, normally the Scroll Rect container Local position</param>
  334. /// <returns>True / False, is the position in the bounds of a page</returns>
  335. internal bool IsRectSettledOnaPage(Vector3 pos)
  336. {
  337. return _isVertical ?
  338. -((pos.y - _scrollStartPosition) / _childSize) == -(int)Math.Round((pos.y - _scrollStartPosition) / _childSize) :
  339. -((pos.x - _scrollStartPosition) / _childSize) == -(int)Math.Round((pos.x - _scrollStartPosition) / _childSize);
  340. }
  341. /// <summary>
  342. /// Returns the local position for a child page based on the required page number
  343. /// </summary>
  344. /// <param name="page">Page that the position is required for (Zero indexed array value)</param>
  345. /// <param name="target">Outputs the local position for the selected page</param>
  346. internal void GetPositionforPage(int page, ref Vector3 target)
  347. {
  348. _childPos = -_childSize * page;
  349. if (_isVertical)
  350. {
  351. _infiniteOffset = _screensContainer.anchoredPosition.y < 0 ? -_screensContainer.sizeDelta.y * _infiniteWindow : _screensContainer.sizeDelta.y * _infiniteWindow;
  352. _infiniteOffset = _infiniteOffset == 0 ? 0 : _infiniteOffset < 0 ? _infiniteOffset - _childSize * _infiniteWindow : _infiniteOffset + _childSize * _infiniteWindow;
  353. target.y = _childPos + _scrollStartPosition + _infiniteOffset;
  354. }
  355. else
  356. {
  357. _infiniteOffset = _screensContainer.anchoredPosition.x < 0 ? -_screensContainer.sizeDelta.x * _infiniteWindow : _screensContainer.sizeDelta.x * _infiniteWindow;
  358. _infiniteOffset = _infiniteOffset == 0 ? 0 : _infiniteOffset < 0 ? _infiniteOffset - _childSize * _infiniteWindow : _infiniteOffset + _childSize * _infiniteWindow;
  359. target.x = _childPos + _scrollStartPosition + _infiniteOffset;
  360. }
  361. }
  362. /// <summary>
  363. /// Updates the _Lerp target to the closest page and updates the pagination bullets. Each control's update loop will then handle the move.
  364. /// </summary>
  365. internal void ScrollToClosestElement()
  366. {
  367. _lerp = true;
  368. CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition);
  369. GetPositionforPage(_currentPage, ref _lerp_target);
  370. OnCurrentScreenChange(_currentPage);
  371. }
  372. /// <summary>
  373. /// notifies pagination indicator and navigation buttons of a screen change
  374. /// </summary>
  375. internal void OnCurrentScreenChange(int currentScreen)
  376. {
  377. ChangeBulletsInfo(currentScreen);
  378. ToggleNavigationButtons(currentScreen);
  379. }
  380. /// <summary>
  381. /// changes the bullets on the bottom of the page - pagination
  382. /// </summary>
  383. /// <param name="targetScreen"></param>
  384. private void ChangeBulletsInfo(int targetScreen)
  385. {
  386. if (Pagination)
  387. {
  388. for (int i = 0; i < Pagination.transform.childCount; i++)
  389. {
  390. Pagination.transform.GetChild(i).GetComponent<Toggle>().isOn = (targetScreen == i) ? true : false;
  391. }
  392. }
  393. }
  394. // Make a lock function for pagination, to prevent event leaking
  395. /// <summary>
  396. /// disables the page navigation buttons when at the first or last screen
  397. /// </summary>
  398. /// <param name="targetScreen"></param>
  399. private void ToggleNavigationButtons(int targetScreen)
  400. {
  401. //If this is using an Infinite Scroll, then don't disable
  402. if (!_isInfinite)
  403. {
  404. if (PrevButton)
  405. {
  406. PrevButton.GetComponent<Button>().interactable = targetScreen > 0;
  407. }
  408. if (NextButton)
  409. {
  410. NextButton.GetComponent<Button>().interactable = targetScreen < _screensContainer.transform.childCount - 1;
  411. }
  412. }
  413. }
  414. private void OnValidate()
  415. {
  416. if (_scroll_rect == null)
  417. {
  418. _scroll_rect = GetComponent<ScrollRect>();
  419. }
  420. if (!_scroll_rect.horizontal && !_scroll_rect.vertical)
  421. {
  422. Debug.LogError("ScrollRect has to have a direction, please select either Horizontal OR Vertical with the appropriate control.");
  423. }
  424. if (_scroll_rect.horizontal && _scroll_rect.vertical)
  425. {
  426. Debug.LogError("ScrollRect has to be unidirectional, only use either Horizontal or Vertical on the ScrollRect, NOT both.");
  427. }
  428. var ScrollRectContent = gameObject.GetComponent<ScrollRect>().content;
  429. if (ScrollRectContent != null)
  430. {
  431. var children = ScrollRectContent.childCount;
  432. if (children != 0 || ChildObjects != null)
  433. {
  434. var childCount = ChildObjects == null || ChildObjects.Length == 0 ? children : ChildObjects.Length;
  435. if (StartingScreen > childCount - 1)
  436. {
  437. StartingScreen = childCount - 1;
  438. }
  439. if (StartingScreen < 0)
  440. {
  441. StartingScreen = 0;
  442. }
  443. }
  444. }
  445. if (MaskBuffer <= 0)
  446. {
  447. MaskBuffer = 1;
  448. }
  449. if (PageStep < 0)
  450. {
  451. PageStep = 0;
  452. }
  453. if (PageStep > 8)
  454. {
  455. PageStep = 9;
  456. }
  457. var infiniteScroll = GetComponent<UI_InfiniteScroll>();
  458. if (ChildObjects != null && ChildObjects.Length > 0 && infiniteScroll != null && !infiniteScroll.InitByUser)
  459. {
  460. Debug.LogError($"[{gameObject.name}]When using procedural children with a ScrollSnap (Adding Prefab ChildObjects) and the Infinite Scroll component\nYou must set the 'InitByUser' option to true, to enable late initialising");
  461. }
  462. }
  463. /// <summary>
  464. /// Event fires when the user starts to change the page, either via swipe or button.
  465. /// </summary>
  466. public void StartScreenChange()
  467. {
  468. if (!_startEventCalled)
  469. {
  470. _suspendEvents = true;
  471. _startEventCalled = true;
  472. _endEventCalled = false;
  473. OnSelectionChangeStartEvent.Invoke();
  474. }
  475. }
  476. /// <summary>
  477. /// Event fires when the currently viewed page changes, also updates while the scroll is moving
  478. /// </summary>
  479. internal void ScreenChange()
  480. {
  481. OnSelectionPageChangedEvent.Invoke(_currentPage);
  482. }
  483. /// <summary>
  484. /// Event fires when control settles on a page, outputs the new page number
  485. /// </summary>
  486. internal void EndScreenChange()
  487. {
  488. if (!_endEventCalled)
  489. {
  490. _suspendEvents = false;
  491. _endEventCalled = true;
  492. _startEventCalled = false;
  493. _settled = true;
  494. OnSelectionChangeEndEvent.Invoke(_currentPage);
  495. }
  496. }
  497. /// <summary>
  498. /// Returns the Transform of the Current page
  499. /// </summary>
  500. /// <returns>Currently selected Page Transform</returns>
  501. public Transform CurrentPageObject()
  502. {
  503. return _screensContainer.GetChild(CurrentPage);
  504. }
  505. /// <summary>
  506. /// Returns the Transform of the Current page in an out parameter for performance
  507. /// </summary>
  508. /// <param name="returnObject">Currently selected Page Transform</param>
  509. public void CurrentPageObject(out Transform returnObject)
  510. {
  511. returnObject = _screensContainer.GetChild(CurrentPage);
  512. }
  513. #region Drag Interfaces
  514. /// <summary>
  515. /// Touch screen to start swiping
  516. /// </summary>
  517. /// <param name="eventData"></param>
  518. public void OnBeginDrag(PointerEventData eventData)
  519. {
  520. _pointerDown = true;
  521. _settled = false;
  522. StartScreenChange();
  523. _startPosition = _screensContainer.anchoredPosition;
  524. }
  525. /// <summary>
  526. /// While dragging do
  527. /// </summary>
  528. /// <param name="eventData"></param>
  529. public void OnDrag(PointerEventData eventData)
  530. {
  531. _lerp = false;
  532. }
  533. public virtual void OnEndDrag(PointerEventData eventData) { }
  534. #endregion
  535. #region IScrollSnap Interface
  536. /// <summary>
  537. /// Added to provide a uniform interface for the ScrollBarHelper
  538. /// </summary>
  539. int IScrollSnap.CurrentPage()
  540. {
  541. return CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition);
  542. }
  543. /// <summary>
  544. /// Added to provide a uniform interface for the ScrollBarHelper
  545. /// </summary>
  546. public void SetLerp(bool value)
  547. {
  548. _lerp = value;
  549. }
  550. /// <summary>
  551. /// Added to provide a uniform interface for the ScrollBarHelper
  552. /// </summary>
  553. public void ChangePage(int page)
  554. {
  555. GoToScreen(page);
  556. }
  557. public void OnPointerClick(PointerEventData eventData)
  558. {
  559. var position = _screensContainer.anchoredPosition;
  560. }
  561. #endregion
  562. }
  563. }