模仿地址:bilibiliuGui
代码如下:
第二段代码继承第一段。
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; //枚举类型 public enum PageScrollType { Horizontal, Vertical } public class PageScrollVive : MonoBehaviour,IBeginDragHandler,IEndDragHandler { #region 字段 protected ScrollRect rect; protected int pageCount; //共有几页 private RectTransform content; protected float[] pages; public float moveTime = 0.3f; //滚动的时间设置为0.3秒 private float timer = 0; //用来计时 private float startMovePos; //开始移动的位置 private int currentPage = 0; //当前页等于0 private bool isDraging = false; //判断是否在拖拽中 private bool isMoving = false; //判断是否移动 public bool IsAutoScroll; //是否开启自动滚动 public float AutoScrollTime = 2; //自动滚动的时间间隔 private float AutoScrollTimer = 0; //计时的 public PageScrollType pageScrollType = PageScrollType.Horizontal; public float vertical; #endregion #region 事件 public Action<int> OnPageChange; //监听事件,晓得当前滚动到了哪一页,用于制作轮播图的小点点 #endregion #region Unity回调函数 // Start is called before the first frame update protected virtual void Start() { Init(); } // Update is called once per frame protected virtual void Update() { ListenerMove(); ListenerAutoScroll(); vertical = rect.verticalNormalizedPosition; } public void OnEndDrag(PointerEventData eventData) { //滚动到离得最近的一页 this.ScrollToPage(CaculateMinDistancePage()); isDraging = false; AutoScrollTimer = 0; } public void OnBeginDrag(PointerEventData eventData) { isDraging = true; //开始拖拽 } #endregion #region 方法 //初始化 public void Init() { rect = transform.GetComponent<ScrollRect>(); if (rect == null) { throw new System.Exception("未查询到ScrollRect!"); } content = transform.Find("Viewport/Content").GetComponent<RectTransform>(); //初始化有多少页 ""中是它的路径 pageCount = content.childCount; if(pageCount ==1 ) { throw new System.Exception("只有一页,不用进行分页滚动"); } pages = new float[pageCount]; for (int i = 0; i < pages.Length; i++) { switch (pageScrollType) { case PageScrollType.Horizontal: pages[i] = i * (1.0f / (float)(pageCount - 1)); //第i页 要转成float类型 break; case PageScrollType.Vertical: pages[i] = 1 - i * (1.0f / (float)(pageCount - 1)); break; } } } //生成一个方法:监听移动 public void ListenerMove() { if (isMoving) { timer += Time.deltaTime * (1 / moveTime); switch (pageScrollType) { case PageScrollType.Horizontal: rect.horizontalNormalizedPosition = Mathf.Lerp(startMovePos, pages[currentPage], timer); break; case PageScrollType.Vertical: rect.verticalNormalizedPosition = Mathf.Lerp(startMovePos, pages[currentPage], timer); break; } //做一个差值运算 从开始移动的位置移动到当前页所处的位置 if (timer >= 1) { isMoving = false; } } } //监听自动滚动 public void ListenerAutoScroll() { if (isDraging) { return; } if (IsAutoScroll) { AutoScrollTimer += Time.deltaTime; if (AutoScrollTimer >= AutoScrollTime) { AutoScrollTimer = 0; //滚动到下一页 currentPage++; currentPage %= pageCount; //解决最后一页回到第一页的问题 ScrollToPage(currentPage); } } } //方法 滚动到指定页 public void ScrollToPage(int page) { isMoving = true; this.currentPage = page; //当前页等于此页 timer = 0; switch (pageScrollType) { case PageScrollType.Horizontal: startMovePos = rect.horizontalNormalizedPosition; break; case PageScrollType.Vertical: startMovePos = rect.verticalNormalizedPosition; break; } if (OnPageChange != null) { OnPageChange(this.currentPage); } } //结束拖拽,计算出离得最近的页 public int CaculateMinDistancePage() { int minPage = 0; //默认离得最近的是第0页 for (int i = 1; i < pages.Length; i++) { switch (pageScrollType) { case PageScrollType.Horizontal: if (Mathf.Abs(pages[i] - rect.horizontalNormalizedPosition) < Mathf.Abs(pages[minPage] - rect.horizontalNormalizedPosition)) { minPage = i; } break; case PageScrollType.Vertical: if (Mathf.Abs(pages[i] - rect.verticalNormalizedPosition) < Mathf.Abs(pages[minPage] - rect.verticalNormalizedPosition)) { minPage = i; } break; } } return minPage; } #endregion }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScalePageScrollVive : PageScrollVive { #region 字段 // 所有页的object private GameObject[] items; public float currentScale = 1f; public float otherScale = 0.6f; public int lastPage; public int nextPage; #endregion #region Unity回调 protected override void Start() { base.Start(); items = new GameObject[pageCount]; //初始化所有的GameObject for (int i = 0; i < pageCount; i++) { items[i] = transform.Find("Viewport/Content").GetChild(i).gameObject; //获取它的子类 } } protected override void Update() { base.Update(); ListenerScale(); } #endregion //监听scale public void ListenerScale() { //找到上一页和下一页 for (int i = 0; i < pages.Length; i++) { if( pages[i] <= rect.horizontalNormalizedPosition ) //若page[i]小于它的位置 则为他的上一页 { lastPage = i; } } for (int i = 0; i < pages.Length; i++) { if (pages[i] > rect.horizontalNormalizedPosition) //若page[i]大于它的位置 则为他的下一页 { nextPage = i; break; //找到第一个就截止 } } if ( nextPage == lastPage ) { return; } float percent = (rect.horizontalNormalizedPosition - pages[lastPage]) / (pages[nextPage] - pages[lastPage]); //5个公告的比例 items[lastPage].transform.localScale = Vector3.Lerp(Vector3.one * currentScale, Vector3.one * otherScale, percent); //上一页的大小 items[nextPage].transform.localScale = Vector3.Lerp(Vector3.one * currentScale, Vector3.one * otherScale, 1 - percent); for (int i = 0; i < items.Length; i++) { if ( i != lastPage && i != nextPage ) { items[i].transform.localScale = Vector3.one * otherScale; } } } }