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
pull/413/head
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
/// 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;
namespace UnityEngine.UI.Extensions
@ -17,21 +15,15 @@ namespace UnityEngine.UI.Extensions
{
isVertical = false;
DistributePages();
if(MaskArea) CalculateVisible();
_lerp = false;
_currentScreen = StartingScreen - 1;
_currentPage = StartingScreen - 1;
_scrollStartPosition = _screensContainer.localPosition.x;
_scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1);
_scroll_rect.horizontalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
}
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)
{
return;
@ -45,15 +37,18 @@ namespace UnityEngine.UI.Extensions
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) ||
_scroll_rect.velocity.x < 0 && _scroll_rect.velocity.x < -SwipeVelocityThreshold)
CurrentPage = GetPageforPosition(_screensContainer.localPosition);
//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);
}
else 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.x > 0 && _scroll_rect.velocity.x < SwipeVelocityThreshold) ||
(_scroll_rect.velocity.x < 0 && _scroll_rect.velocity.x > -SwipeVelocityThreshold))
{
ScrollToClosestElement();
}
}
}
@ -95,7 +90,7 @@ namespace UnityEngine.UI.Extensions
GO.transform.SetParent(_screensContainer);
DistributePages();
_scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1);
_scroll_rect.horizontalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
}
/// <summary>
@ -127,12 +122,12 @@ namespace UnityEngine.UI.Extensions
DistributePages();
if (_currentScreen > _screens - 1)
if (_currentPage > _screens - 1)
{
CurrentPage = _screens - 1;
}
_scroll_rect.horizontalNormalizedPosition = (float)(_currentScreen) / (_screens - 1);
_scroll_rect.horizontalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
}
#region Interfaces
@ -147,7 +142,8 @@ namespace UnityEngine.UI.Extensions
if (UseFastSwipe)
{
//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;
if (_startPosition.x - _screensContainer.localPosition.x > 0)
@ -166,7 +162,6 @@ namespace UnityEngine.UI.Extensions
}
}
}
#endregion
}
}

View File

@ -8,7 +8,7 @@ namespace UnityEngine.UI.Extensions
{
public class ScrollSnapBase : MonoBehaviour, IBeginDragHandler, IDragHandler, IPointerDownHandler, IPointerUpHandler
{
public RectTransform _screensContainer;
internal RectTransform _screensContainer;
internal bool isVertical;
internal int _screens = 1;
@ -20,6 +20,12 @@ namespace UnityEngine.UI.Extensions
internal Vector3 _lerp_target;
internal bool _lerp;
internal bool _pointerDown = false;
internal Vector3 _startPosition = new Vector3();
[Tooltip("The currently active page")]
internal int _currentPage;
internal int _previousPage;
[Serializable]
public class SelectionChangeStartEvent : UnityEvent { }
@ -48,15 +54,9 @@ namespace UnityEngine.UI.Extensions
public Boolean UseFastSwipe = false;
[Tooltip("How far swipe has to travel to initiate a page change (optional)")]
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;
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")]
[SerializeField]
public int StartingScreen = 1;
@ -70,16 +70,16 @@ namespace UnityEngine.UI.Extensions
{
get
{
return _currentScreen;
return _currentPage;
}
internal set
{
if (value != _currentScreen)
if (value != _currentPage)
{
_previousScreen = _currentScreen;
_currentScreen = value;
ChangeBulletsInfo(_currentScreen);
UpdateVisible();
_previousPage = _currentPage;
_currentPage = value;
ChangeBulletsInfo(_currentPage);
if(MaskArea) UpdateVisible();
}
}
}
@ -163,52 +163,42 @@ namespace UnityEngine.UI.Extensions
void UpdateVisible()
{
int BottomItem = _currentScreen - HalfNoVisibleItems < 0 ? 0 : HalfNoVisibleItems;
int TopItem = _screensContainer.childCount - _currentScreen < HalfNoVisibleItems ? _screensContainer.childCount - _currentScreen : HalfNoVisibleItems;
int BottomItem = _currentPage - HalfNoVisibleItems < 0 ? 0 : HalfNoVisibleItems;
int TopItem = _screensContainer.childCount - _currentPage < HalfNoVisibleItems ? _screensContainer.childCount - _currentPage : HalfNoVisibleItems;
for (int i = CurrentPage - BottomItem; i < CurrentPage + TopItem; i++)
{
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 (_previousScreen < _currentScreen)
//{
// 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);
//}
if (_screensContainer.childCount - _currentPage > HalfNoVisibleItems + 1) ChildObjects[CurrentPage + TopItem + 1].SetActive(false);
if(_currentPage - HalfNoVisibleItems > 0) ChildObjects[CurrentPage - BottomItem - 1].SetActive(false);
}
//Function for switching screens with buttons
public void NextScreen()
{
if (_currentScreen < _screens - 1)
if (_currentPage < _screens - 1)
{
if (!_lerp) StartScreenChange();
_lerp = true;
CurrentPage = _currentScreen + 1;
GetPositionforPage(_currentScreen, ref _lerp_target);
CurrentPage = _currentPage + 1;
GetPositionforPage(_currentPage, ref _lerp_target);
}
}
//Function for switching screens with buttons
public void PreviousScreen()
{
if (_currentScreen > 0)
if (_currentPage > 0)
{
if (!_lerp) StartScreenChange();
_lerp = true;
CurrentPage = _currentScreen - 1;
GetPositionforPage(_currentScreen, ref _lerp_target);
CurrentPage = _currentPage - 1;
GetPositionforPage(_currentPage, ref _lerp_target);
}
}
@ -225,7 +215,7 @@ namespace UnityEngine.UI.Extensions
_lerp = true;
CurrentPage = screenIndex;
GetPositionforPage(_currentScreen, ref _lerp_target);
GetPositionforPage(_currentPage, ref _lerp_target);
}
}
@ -254,8 +244,8 @@ namespace UnityEngine.UI.Extensions
{
_lerp = true;
CurrentPage = GetPageforPosition(_screensContainer.localPosition);
GetPositionforPage(_currentScreen, ref _lerp_target);
ChangeBulletsInfo(_currentScreen);
GetPositionforPage(_currentPage, ref _lerp_target);
ChangeBulletsInfo(_currentPage);
}
//changes the bullets on the bottom of the page - pagination
@ -291,7 +281,7 @@ namespace UnityEngine.UI.Extensions
internal void ScreenChange(int previousScreen)
{
OnSelectionPageChangedEvent.Invoke(_currentScreen);
OnSelectionPageChangedEvent.Invoke(_currentPage);
}
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 - major refactoring on updating current position and scroll management
using System;
using UnityEngine.Events;
using UnityEngine.EventSystems;
namespace UnityEngine.UI.Extensions
@ -17,22 +15,15 @@ namespace UnityEngine.UI.Extensions
{
isVertical = true;
DistributePages();
CalculateVisible();
if(MaskArea) CalculateVisible();
_lerp = false;
_currentScreen = StartingScreen - 1;
_currentPage = StartingScreen - 1;
_scrollStartPosition = _screensContainer.localPosition.y;
_scroll_rect.verticalNormalizedPosition = (float)(_currentScreen) / (float)(_screens - 1);
_scroll_rect.verticalNormalizedPosition = (float)(_currentPage) / (float)(_screens - 1);
}
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)
{
return;
@ -46,16 +37,20 @@ namespace UnityEngine.UI.Extensions
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) ||
// _scroll_rect.velocity.y < 0 && _scroll_rect.velocity.y < -SwipeVelocityThreshold)
//{
CurrentPage = GetPageforPosition(_screensContainer.localPosition);
//}
if(!_pointerDown)
CurrentPage = GetPageforPosition(_screensContainer.localPosition);
//If the container is moving check if it needs to settle on a page
if (!_pointerDown && (_scroll_rect.velocity.y > 0.01 || _scroll_rect.velocity.y < -0.01))
{
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
@ -95,7 +90,7 @@ namespace UnityEngine.UI.Extensions
GO.transform.SetParent(_screensContainer);
DistributePages();
_scroll_rect.verticalNormalizedPosition = (float)(_currentScreen) / (_screens - 1);
_scroll_rect.verticalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
}
/// <summary>
@ -126,12 +121,12 @@ namespace UnityEngine.UI.Extensions
}
DistributePages();
if (_currentScreen > _screens - 1)
if (_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 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;
if (_startPosition.y - _screensContainer.localPosition.y > 0)
@ -166,7 +162,6 @@ namespace UnityEngine.UI.Extensions
}
}
}
#endregion
}
}