//基础手动/自动滚动代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PstPanel : MonoBehaviour ,IEndDragHandler,IBeginDragHandler
{
protected ScrollRect rect;
RectTransform content;
public int pageCount;
public float[] pagePos;//存储各滚动页的坐标
public float runTime = 0;//控制滚动快慢的记录系统时间
public float holdTime = 0.2f;//控制滚动快慢的时间
public float startPos;//滚动窗口rect.horizontalNormalizedPosition属性线性变化的开始值
public int currentPage = 0;//当前滚动窗口要显示页面
public bool isMoving = false;
public bool isAutoRoll;
public float autoHodeTime = 2;//自动股东间隔时间
private float AutoRunTimer=0;//控制自动滚动间隔的记录系统时间
private bool isDrag = false;
public Action<int> OnPageChange;//事件/委托链:公开变量用于外部订阅
// Start is called before the first frame update
protected virtual void Start()
{
Init();
}
private void Init()
{
rect = GetComponent<ScrollRect>();
content = transform.Find("Viewport/Content").GetComponent<RectTransform>();
pageCount = content.childCount;
if (pageCount == 1)
{
throw new System.Exception("UnAutoR");
}
pagePos = new float[pageCount];
for (int i = 0; i < pagePos.Length; i++)
{
pagePos[i] = i * (1.0f / (float)(pageCount - 1));//计算并存储每个页面的坐标
}
}
// Update is called once per frame
protected virtual void Update()
{
LisenerMove();//监听移动方法
LisenerAutoRoll();//监听自动移动方法
}
private void LisenerMove()//每帧执行:使窗口显示目标页面
{
if (isMoving)
{
runTime += Time.deltaTime / holdTime;
rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, pagePos[currentPage], runTime);//runTime=1时立即移动到目标值
if (runTime >= 1)
{
isMoving = false;
}
}
}
public void LisenerAutoRoll()
{
if (isDrag) return;
if (isAutoRoll)//间隔时间调用滚动方法
{
AutoRunTimer += Time.deltaTime;
if(AutoRunTimer>=autoHodeTime)
{
AutoRunTimer = 0;
currentPage++ ;
currentPage %= pageCount;
ScrollToPage(currentPage);
}
}
}
/// <summary>
/// 滚动到指定页面方法
/// </summary>
/// <param name="page">要滚动到的页面</param>
public void ScrollToPage(int page)
{
isMoving = true;
currentPage =page;
runTime = 0;
startPos = rect.horizontalNormalizedPosition;//范围(0~1)
if(OnPageChange!=null)// OnPageChange?.Invoke(this.currentPage);
{//作用同于广播此事件(委托连不为空则调用)
OnPageChange(this.currentPage);
}
}
public void OnEndDrag(PointerEventData eventData)//结束拖拽接口实现:重置自动滚动时间,判断当前停留位置更接近那个页面并移动到目标页面
{
isDrag = false;
AutoRunTimer = 0;
ToEndPos();
}
/// <summary>
/// 拖拽结束时一定到目标位置
/// </summary>
private void ToEndPos()
{
int pageIndex = 0;
for (int i = 1; i < pagePos.Length; i++)
{
if (Mathf.Abs(pagePos[i] - rect.horizontalNormalizedPosition) < Mathf.Abs(pagePos[pageIndex] - rect.horizontalNormalizedPosition))
{
pageIndex = i;
}
}
ScrollToPage(pageIndex);
}
public void OnBeginDrag(PointerEventData eventData)//开始拖拽接口实现
{
isDrag = true;
}
}
//通过代码继承与多态对父类代码复用与扩展添加缓动效果
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PageScale : PstPanel
{
public GameObject[] items;
public float currentScle = 1f;
public float otherScle = 0.6f;
public int lastPage;
public int nextPage;
public float percent;
protected override void Start()
{
base.Start();
items = new GameObject[pageCount];
for (int i = 0; i < pageCount; i++)
{
items[i] = transform.Find("Viewport/Content").transform.GetChild(i).gameObject;
}
}
protected override void Update()
{
base.Update();
LissenterScale();
//SetItenSize(currentPage);
}
/// <summary>
/// 监听Scale
/// </summary>
public void LissenterScale()
{
//获取当前上一页,下一页
for (int i = 0; i < pagePos.Length; i++)
{
if(pagePos[i]<=rect.horizontalNormalizedPosition)
{
lastPage = i;
}
}
for (int i = 0; i < pagePos.Length; i++)
{
if(pagePos[i]>rect.horizontalNormalizedPosition)
{
nextPage = i;
break;
}
}
if (lastPage == nextPage)
return;
percent = (rect.horizontalNormalizedPosition - pagePos[lastPage]) / (pagePos[nextPage] - pagePos[lastPage]);//当前页到下一页0~1变动
items[lastPage].transform.localScale = Vector3.Lerp(Vector3.one * currentScle, Vector3.one * otherScle, percent);//按比例返回a,b间的值0返回a,1返回b
items[nextPage].transform.localScale = Vector3.Lerp(Vector3.one * currentScle, Vector3.one * otherScle, 1-percent);
for (int i = 0; i < items.Length; i++)
{
if (i!=lastPage&&i!=nextPage)
items[i].transform.localScale = Vector3.one * otherScle;
}
}
}