Unity点击按钮实现翻页效果
2021-10-13 本文已影响0人
小骄傲999
image
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using UnityEngine.EventSystems;
using System;
[RequireComponent(typeof(ScrollRect))]
public class UIPage : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
public GameObject btnPrior;
public GameObject btnNext;
public bool needArrowTween = false;
public Scrollbar scrollbar;
public int OnePageNum; //每页多少个
public float curDur = 0.3f; //动画duration
public bool isLerp = true; //平滑移动
public Vector2 cellSize; //cellSize包括spacing 如果不是特例且Scroll的Content是GridLayoutGroup可不赋值
public float surpassScale = 0.7f; //超过本页第一个项Size的多少比例算作已读
public bool AutoRelocate;
public float RelocatePassDis = 100;
public bool IgnoreCellMode;
public bool IsButtonCanClick;
private bool _scrolling;
public bool Scrolling
{
get { return _scrolling; }
}
bool isVertical;
Vector3 defaultPos;
int childCount;
void Awake()
{
isVertical = scroll.vertical;
if (cellSize.x == 0 && cellSize.y == 0)
cellSize = getGroup().cellSize + getGroup().spacing;
if (IsButtonCanClick)
{
if (btnPrior)
{
btnPrior.GetComponent<Button>().onClick.AddListener(delegate { OnButtonPress(!isVertical); });
if (needArrowTween)
btnPrior.transform.DOLocalMoveX(-347, 0.5f).SetLoops(-1, LoopType.Yoyo);
}
if (btnNext)
{
btnNext.GetComponent<Button>().onClick.AddListener(delegate { OnButtonPress(isVertical); });
if (needArrowTween)
btnNext.transform.DOLocalMoveX(347, 0.5f).SetLoops(-1, LoopType.Yoyo);
}
}
}
void Start()
{
if (isVertical)
defaultPos = new Vector2(gRect.anchoredPosition.x, 0);
else
defaultPos = new Vector2(0, gRect.anchoredPosition.y);
}
void LateUpdate()
{
for (int i = 0; i < gRect.transform.childCount; i++)
{
if (gRect.transform.GetChild(i).gameObject.activeSelf)
childCount++;
}
if (childCount > OnePageNum)
{
var pos = isVertical ? scroll.verticalNormalizedPosition : scroll.horizontalNormalizedPosition;
if (btnPrior)
btnPrior.SetActive(isVertical ? (pos < 0.99999f) : (pos > 0.02f));
if (btnNext)
btnNext.SetActive(isVertical ? (pos > 0.0001f) : (pos < 0.999f));
}
else
{
gRect.anchoredPosition = defaultPos;
if (btnPrior)
btnPrior.SetActive(false);
if (btnNext)
btnNext.SetActive(false);
}
childCount = 0;
}
public void OnButtonPress(bool isNext)
{
StopAllCoroutines();
if (isNext)
NextPage();
else
PriorPage();
}
public void NextPage()
{
if (_scrolling)
return;
float cellScale = 0f;
float pos = isVertical ? scroll.verticalNormalizedPosition : scroll.horizontalNormalizedPosition;
if (IgnoreCellMode)
{
float sRectVal = isVertical ? sRect.rect.height : sRect.rect.width;
float gRectVal = isVertical ? gRect.rect.height : gRect.rect.width;
var ratio = sRectVal / (gRectVal - sRectVal);
ScrollPage(pos + ratio);
}
cellScale = (isVertical ? cellSize.y : cellSize.x) /
(isVertical ? gRect.rect.height - sRect.rect.height : gRect.rect.width - sRect.rect.width);
int priorGrid = (int) ((1f - pos) / cellScale);
if ((1f - pos) / cellScale - priorGrid > surpassScale)
priorGrid++;
float offset = (1f - pos) - cellScale * priorGrid;
if (!isLerp)
{
if (isVertical)
scroll.verticalNormalizedPosition -= (cellScale * getPageNum() - offset);
else
scroll.horizontalNormalizedPosition -= (cellScale * getPageNum() - offset);
}
else
{
float value = -(cellScale * getPageNum() - offset);
if ((pos + value) < 0)
value = -pos;
ScrollPage(pos + value);
}
}
public void PriorPage()
{
if (_scrolling)
return;
float cellScale = 0f;
float pos = isVertical ? scroll.verticalNormalizedPosition : scroll.horizontalNormalizedPosition;
if (IgnoreCellMode)
{
float sRectVal = isVertical ? sRect.rect.height : sRect.rect.width;
float gRectVal = isVertical ? gRect.rect.height : gRect.rect.width;
var ratio = sRectVal / (gRectVal - sRectVal);
ScrollPage(pos - ratio);
}
cellScale = (isVertical ? cellSize.y : cellSize.x) /
(isVertical ? gRect.rect.height - sRect.rect.height : gRect.rect.width - sRect.rect.width);
int nextGrid = (int) (pos / cellScale);
if ((pos / cellScale) - nextGrid > surpassScale)
nextGrid++;
float offset = pos - cellScale * nextGrid;
if (!isLerp)
{
if (isVertical)
scroll.verticalNormalizedPosition += (cellScale * getPageNum() - offset);
else
scroll.horizontalNormalizedPosition += (cellScale * getPageNum() - offset);
}
else
{
int pageNum = getPageNum();
float value = (cellScale * pageNum - offset);
if ((pos + value) > 1)
value = 1 - pos;
ScrollPage(pos + value);
}
}
void ScrollPage(float toPos)
{
_scrolling = true;
float fromPos = isVertical ? scroll.verticalNormalizedPosition : scroll.horizontalNormalizedPosition;
DOTween.To((delegate(float v)
{
if (isVertical)
scroll.verticalNormalizedPosition = v;
else
scroll.horizontalNormalizedPosition = v;
}), fromPos, toPos, 0.3f).OnComplete(delegate { _scrolling = false; });
}
int getPageNum()
{
float pageNum = 0;
if (isVertical)
pageNum = sRect.rect.height / cellSize.y;
else
pageNum = sRect.rect.width / cellSize.x;
if (pageNum - (int) pageNum > 0.9f)
pageNum = (int) pageNum + 1;
return (int) pageNum;
}
GridLayoutGroup getGroup()
{
if (group_ == null)
{
var group = scroll.content.gameObject.GetComponent<GridLayoutGroup>();
if (group == null)
return null;
else
group_ = group;
}
return group_;
}
Vector2 startPos;
Vector2 startNormalizePos;
public void OnBeginDrag(PointerEventData eventData)
{
if (!AutoRelocate)
return;
startPos = eventData.position;
startNormalizePos = scroll.normalizedPosition;
}
public void OnEndDrag(PointerEventData eventData)
{
if (!AutoRelocate)
return;
Vector2 normalizePos = scroll.normalizedPosition;
if (normalizePos.x > 1 || normalizePos.x < 0 || normalizePos.y > 1 || normalizePos.y < 0)
return;
Vector2 offset = eventData.position - startPos;
if (isVertical)
{
if (Mathf.Abs(offset.y) > RelocatePassDis)
{
if (offset.y > 0)
NextPage();
else
PriorPage();
}
else
{
ScrollPage(startNormalizePos.y);
}
}
else
{
if (Mathf.Abs(offset.x) > RelocatePassDis)
{
if (offset.x > 0)
NextPage();
else
PriorPage();
}
else
{
ScrollPage(startNormalizePos.x);
}
}
}
ScrollRect scroll_;
ScrollRect scroll
{
get
{
if (scroll_ == null)
scroll_ = gameObject.GetComponent<ScrollRect>();
return scroll_;
}
}
GridLayoutGroup group_;
RectTransform gRect
{
get { return scroll_.content; }
}
RectTransform sRect_;
RectTransform sRect
{
get
{
if (sRect_ == null)
sRect_ = gameObject.GetComponent<RectTransform>();
return sRect_;
}
}
}