Almost complete:

* Scrolling - working
* Fast Swipe - working (as well as Unity can fast swipe :S)
* Mask with only visible items - working
* Jump to page - working

Just found a bug with removing / adding items

--HG--
branch : develop_5.3
release
Simon Jackson 2016-12-21 16:52:19 +00:00
parent 4bd100c7e9
commit a72c45e02a
3 changed files with 69 additions and 89 deletions

View File

@ -2,8 +2,6 @@
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1945602 /// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/page-2#post-1945602
/// Updated by ddreaper - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect. /// Updated by ddreaper - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
using System;
using UnityEngine.Events;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
@ -17,21 +15,15 @@ namespace UnityEngine.UI.Extensions
{ {
isVertical = false; isVertical = false;
DistributePages(); DistributePages();
if(MaskArea) CalculateVisible();
_lerp = false; _lerp = false;
_currentScreen = StartingScreen - 1; _currentPage = StartingScreen - 1;
_scrollStartPosition = _screensContainer.localPosition.x; _scrollStartPosition = _screensContainer.localPosition.x;
_scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); _scroll_rect.horizontalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
} }
void Update() void Update()
{ {
//Three Use cases:
//1: Swipe Next - FastSwipeNextPrev
//2: Swipe next while in motion - FastSwipeNextPrev
//3: Swipe to end - default
//If lerping, NOT swiping and (!fastswipenextprev & velocity < 200)
//Aim is to settle on target "page"
if (!_lerp && _scroll_rect.velocity == Vector2.zero) if (!_lerp && _scroll_rect.velocity == Vector2.zero)
{ {
return; return;
@ -45,15 +37,18 @@ namespace UnityEngine.UI.Extensions
EndScreenChange(); EndScreenChange();
} }
} }
//If the container is moving faster than the threshold, then just update the pages as they pass
else if ((_scroll_rect.velocity.x > 0 && _scroll_rect.velocity.x > SwipeVelocityThreshold) || CurrentPage = GetPageforPosition(_screensContainer.localPosition);
_scroll_rect.velocity.x < 0 && _scroll_rect.velocity.x < -SwipeVelocityThreshold)
//If the container is moving check if it needs to settle on a page
if (!_pointerDown && (_scroll_rect.velocity.x > 0.01 || _scroll_rect.velocity.x < 0.01))
{ {
CurrentPage = GetPageforPosition(_screensContainer.localPosition); // if the pointer is released and is moving slower than the threshold, then just land on a page
} if ((_scroll_rect.velocity.x > 0 && _scroll_rect.velocity.x < SwipeVelocityThreshold) ||
else if (!_pointerDown) (_scroll_rect.velocity.x < 0 && _scroll_rect.velocity.x > -SwipeVelocityThreshold))
{ {
ScrollToClosestElement(); ScrollToClosestElement();
}
} }
} }
@ -95,7 +90,7 @@ namespace UnityEngine.UI.Extensions
GO.transform.SetParent(_screensContainer); GO.transform.SetParent(_screensContainer);
DistributePages(); DistributePages();
_scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); _scroll_rect.horizontalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
} }
/// <summary> /// <summary>
@ -127,12 +122,12 @@ namespace UnityEngine.UI.Extensions
DistributePages(); DistributePages();
if (_currentScreen > _screens - 1) if (_currentPage > _screens - 1)
{ {
CurrentPage = _screens - 1; CurrentPage = _screens - 1;
} }
_scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); _scroll_rect.horizontalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
} }
#region Interfaces #region Interfaces
@ -147,7 +142,8 @@ namespace UnityEngine.UI.Extensions
if (UseFastSwipe) if (UseFastSwipe)
{ {
//If using fastswipe - then a swipe does page next / previous //If using fastswipe - then a swipe does page next / previous
if (_scroll_rect.velocity.x > SwipeVelocityThreshold) if ((_scroll_rect.velocity.x > 0 &&_scroll_rect.velocity.x > FastSwipeThreshold) ||
_scroll_rect.velocity.x < 0 && _scroll_rect.velocity.x < -FastSwipeThreshold)
{ {
_scroll_rect.velocity = Vector3.zero; _scroll_rect.velocity = Vector3.zero;
if (_startPosition.x - _screensContainer.localPosition.x > 0) if (_startPosition.x - _screensContainer.localPosition.x > 0)
@ -166,7 +162,6 @@ namespace UnityEngine.UI.Extensions
} }
} }
} }
#endregion #endregion
} }
} }

View File

@ -8,7 +8,7 @@ namespace UnityEngine.UI.Extensions
{ {
public class ScrollSnapBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IPointerDownHandler, IPointerUpHandler public class ScrollSnapBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IPointerDownHandler, IPointerUpHandler
{ {
public RectTransform _screensContainer; internal RectTransform _screensContainer;
internal bool isVertical; internal bool isVertical;
internal int _screens = 1; internal int _screens = 1;
@ -20,6 +20,12 @@ namespace UnityEngine.UI.Extensions
internal Vector3 _lerp_target; internal Vector3 _lerp_target;
internal bool _lerp; internal bool _lerp;
internal bool _pointerDown = false; internal bool _pointerDown = false;
internal Vector3 _startPosition = new Vector3();
[Tooltip("The currently active page")]
internal int _currentPage;
internal int _previousPage;
[Serializable] [Serializable]
public class SelectionChangeStartEvent : UnityEvent { } public class SelectionChangeStartEvent : UnityEvent { }
@ -48,15 +54,9 @@ namespace UnityEngine.UI.Extensions
public Boolean UseFastSwipe = false; public Boolean UseFastSwipe = false;
[Tooltip("How far swipe has to travel to initiate a page change (optional)")] [Tooltip("How far swipe has to travel to initiate a page change (optional)")]
public int FastSwipeThreshold = 100; public int FastSwipeThreshold = 100;
[Tooltip("How fast can a user swipe to be a swipe (optional)")] [Tooltip("Speed at which the ScrollRect will keep scrolling before slowing down and stopping (optional)")]
public int SwipeVelocityThreshold = 200; public int SwipeVelocityThreshold = 200;
internal Vector3 _startPosition = new Vector3();
[Tooltip("The currently active page")]
internal int _currentScreen;
internal int _previousScreen;
[Tooltip("The screen / page to start the control on")] [Tooltip("The screen / page to start the control on")]
[SerializeField] [SerializeField]
public int StartingScreen = 1; public int StartingScreen = 1;
@ -70,16 +70,16 @@ namespace UnityEngine.UI.Extensions
{ {
get get
{ {
return _currentScreen; return _currentPage;
} }
internal set internal set
{ {
if (value != _currentScreen) if (value != _currentPage)
{ {
_previousScreen = _currentScreen; _previousPage = _currentPage;
_currentScreen = value; _currentPage = value;
ChangeBulletsInfo(_currentScreen); ChangeBulletsInfo(_currentPage);
UpdateVisible(); if(MaskArea) UpdateVisible();
} }
} }
} }
@ -163,52 +163,42 @@ namespace UnityEngine.UI.Extensions
void UpdateVisible() void UpdateVisible()
{ {
int BottomItem = _currentScreen - HalfNoVisibleItems < 0 ? 0 : HalfNoVisibleItems; int BottomItem = _currentPage - HalfNoVisibleItems < 0 ? 0 : HalfNoVisibleItems;
int TopItem = _screensContainer.childCount - _currentScreen < HalfNoVisibleItems ? _screensContainer.childCount - _currentScreen : HalfNoVisibleItems; int TopItem = _screensContainer.childCount - _currentPage < HalfNoVisibleItems ? _screensContainer.childCount - _currentPage : HalfNoVisibleItems;
for (int i = CurrentPage - BottomItem; i < CurrentPage + TopItem; i++) for (int i = CurrentPage - BottomItem; i < CurrentPage + TopItem; i++)
{ {
ChildObjects[i].SetActive(true); ChildObjects[i].SetActive(true);
} }
if(_screensContainer.childCount - _currentScreen > HalfNoVisibleItems) ChildObjects[CurrentPage + TopItem + 1].SetActive(false);
if(_currentScreen - HalfNoVisibleItems > 0) ChildObjects[CurrentPage - BottomItem - 1].SetActive(false); if (_screensContainer.childCount - _currentPage > HalfNoVisibleItems + 1) ChildObjects[CurrentPage + TopItem + 1].SetActive(false);
//if (_previousScreen < _currentScreen) if(_currentPage - HalfNoVisibleItems > 0) ChildObjects[CurrentPage - BottomItem - 1].SetActive(false);
//{
// ChildObjects[TopItem].SetActive(true);
// if(TopItem < _screensContainer.childCount - HalfNoVisibleItems) ChildObjects[TopItem + 1].SetActive(true);
// ChildObjects[BottomItem].SetActive(false);
//}
//else
//{
// ChildObjects[TopItem].SetActive(false);
// ChildObjects[BottomItem].SetActive(true);
// if(BottomItem > 0) ChildObjects[BottomItem - 1].SetActive(true);
//}
} }
//Function for switching screens with buttons //Function for switching screens with buttons
public void NextScreen() public void NextScreen()
{ {
if (_currentScreen < _screens - 1) if (_currentPage < _screens - 1)
{ {
if (!_lerp) StartScreenChange(); if (!_lerp) StartScreenChange();
_lerp = true; _lerp = true;
CurrentPage = _currentScreen + 1; CurrentPage = _currentPage + 1;
GetPositionforPage(_currentScreen, ref _lerp_target); GetPositionforPage(_currentPage, ref _lerp_target);
} }
} }
//Function for switching screens with buttons //Function for switching screens with buttons
public void PreviousScreen() public void PreviousScreen()
{ {
if (_currentScreen > 0) if (_currentPage > 0)
{ {
if (!_lerp) StartScreenChange(); if (!_lerp) StartScreenChange();
_lerp = true; _lerp = true;
CurrentPage = _currentScreen - 1; CurrentPage = _currentPage - 1;
GetPositionforPage(_currentScreen, ref _lerp_target); GetPositionforPage(_currentPage, ref _lerp_target);
} }
} }
@ -225,7 +215,7 @@ namespace UnityEngine.UI.Extensions
_lerp = true; _lerp = true;
CurrentPage = screenIndex; CurrentPage = screenIndex;
GetPositionforPage(_currentScreen, ref _lerp_target); GetPositionforPage(_currentPage, ref _lerp_target);
} }
} }
@ -254,8 +244,8 @@ namespace UnityEngine.UI.Extensions
{ {
_lerp = true; _lerp = true;
CurrentPage = GetPageforPosition(_screensContainer.localPosition); CurrentPage = GetPageforPosition(_screensContainer.localPosition);
GetPositionforPage(_currentScreen, ref _lerp_target); GetPositionforPage(_currentPage, ref _lerp_target);
ChangeBulletsInfo(_currentScreen); ChangeBulletsInfo(_currentPage);
} }
//changes the bullets on the bottom of the page - pagination //changes the bullets on the bottom of the page - pagination
@ -291,7 +281,7 @@ namespace UnityEngine.UI.Extensions
internal void ScreenChange(int previousScreen) internal void ScreenChange(int previousScreen)
{ {
OnSelectionPageChangedEvent.Invoke(_currentScreen); OnSelectionPageChangedEvent.Invoke(_currentPage);
} }
internal void EndScreenChange() internal void EndScreenChange()

View File

@ -3,8 +3,6 @@
/// Updated by SimonDarksideJ - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect. /// Updated by SimonDarksideJ - removed dependency on a custom ScrollRect script. Now implements drag interfaces and standard Scroll Rect.
/// Updated by SimonDarksideJ - major refactoring on updating current position and scroll management /// Updated by SimonDarksideJ - major refactoring on updating current position and scroll management
using System;
using UnityEngine.Events;
using UnityEngine.EventSystems; using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions namespace UnityEngine.UI.Extensions
@ -17,22 +15,15 @@ namespace UnityEngine.UI.Extensions
{ {
isVertical = true; isVertical = true;
DistributePages(); DistributePages();
CalculateVisible(); if(MaskArea) CalculateVisible();
_lerp = false; _lerp = false;
_currentScreen = StartingScreen - 1; _currentPage = StartingScreen - 1;
_scrollStartPosition = _screensContainer.localPosition.y; _scrollStartPosition = _screensContainer.localPosition.y;
_scroll_rect.verticalNormalizedPosition = (float)(_currentScreen) / (float)(_screens - 1); _scroll_rect.verticalNormalizedPosition = (float)(_currentPage) / (float)(_screens - 1);
} }
void Update() void Update()
{ {
//Three Use cases:
//1: Swipe Next - FastSwipeNextPrev
//2: Swipe next while in motion - FastSwipeNextPrev
//3: Swipe to end - default
//If lerping, NOT swiping and (!fastswipenextprev & velocity < 200)
//Aim is to settle on target "page"
if (!_lerp && _scroll_rect.velocity == Vector2.zero) if (!_lerp && _scroll_rect.velocity == Vector2.zero)
{ {
return; return;
@ -46,16 +37,20 @@ namespace UnityEngine.UI.Extensions
EndScreenChange(); EndScreenChange();
} }
} }
//If the container is moving faster than the threshold, then just update the pages as they pass
//else if ((_scroll_rect.velocity.y > 0 && _scroll_rect.velocity.y > SwipeVelocityThreshold) || CurrentPage = GetPageforPosition(_screensContainer.localPosition);
// _scroll_rect.velocity.y < 0 && _scroll_rect.velocity.y < -SwipeVelocityThreshold)
//{ //If the container is moving check if it needs to settle on a page
CurrentPage = GetPageforPosition(_screensContainer.localPosition); if (!_pointerDown && (_scroll_rect.velocity.y > 0.01 || _scroll_rect.velocity.y < -0.01))
//}
if(!_pointerDown)
{ {
ScrollToClosestElement(); // if the pointer is released and is moving slower than the threshold, then just land on a page
if ((_scroll_rect.velocity.y > 0 && _scroll_rect.velocity.y < SwipeVelocityThreshold) ||
(_scroll_rect.velocity.y < 0 && _scroll_rect.velocity.y > -SwipeVelocityThreshold))
{
ScrollToClosestElement();
}
} }
} }
//used for changing between screen resolutions //used for changing between screen resolutions
@ -95,7 +90,7 @@ namespace UnityEngine.UI.Extensions
GO.transform.SetParent(_screensContainer); GO.transform.SetParent(_screensContainer);
DistributePages(); DistributePages();
_scroll_rect.verticalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); _scroll_rect.verticalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
} }
/// <summary> /// <summary>
@ -126,12 +121,12 @@ namespace UnityEngine.UI.Extensions
} }
DistributePages(); DistributePages();
if (_currentScreen > _screens - 1) if (_currentPage > _screens - 1)
{ {
CurrentPage = _screens - 1; CurrentPage = _screens - 1;
} }
_scroll_rect.verticalNormalizedPosition = (float)(_currentScreen) / (_screens - 1); _scroll_rect.verticalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
} }
@ -147,7 +142,8 @@ namespace UnityEngine.UI.Extensions
if (UseFastSwipe) if (UseFastSwipe)
{ {
//If using fastswipe - then a swipe does page next / previous //If using fastswipe - then a swipe does page next / previous
if (_scroll_rect.velocity.y > SwipeVelocityThreshold) if ((_scroll_rect.velocity.y > 0 && _scroll_rect.velocity.y > FastSwipeThreshold) ||
_scroll_rect.velocity.y < 0 && _scroll_rect.velocity.y < -FastSwipeThreshold)
{ {
_scroll_rect.velocity = Vector3.zero; _scroll_rect.velocity = Vector3.zero;
if (_startPosition.y - _screensContainer.localPosition.y > 0) if (_startPosition.y - _screensContainer.localPosition.y > 0)
@ -166,7 +162,6 @@ namespace UnityEngine.UI.Extensions
} }
} }
} }
#endregion #endregion
} }
} }