记录一下模仿的小demo

模仿地址:bilibiliuGui

记录一下模仿的小demo

代码如下:

第二段代码继承第一段。

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;
            }
        }
    }

}

 

上一篇:janvas 概览


下一篇:【Unity学习笔记】Rect Transform组件