unity 利用Scroll View实现滑动翻页效果

文章介绍了如何在Unity中使用ScrollRect组件创建可滚动的ScrollView,并实现页数控制和左右翻页功能,包括滑动处理和页数变更的响应逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.在Hierarchy视图右键创建UI->Scroll View。

Scrollbar可根据自己需求选择是否删除,我这里制作的翻页日历用不上我就删除了。

connect节点挂上Grid Layout Group组件,参数属性可参考unity API。

下面是具体实现代码

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using System;

public class PageView : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{

    private ScrollRect rect;                        //滑动组件  
    private float targethorizontal = 0;             //滑动的起始坐标  
    private bool isDrag = false;                    //是否拖拽结束  
    private List<float> posList = new List<float>();//求出每页的临界角,页索引从0开始  
    private int currentPageIndex = -1;
    public Action<int> OnPageChanged;
    public RectTransform content;
    private bool stopMove = true;
    public float smooting = 2;                      //滑动速度  
    public float sensitivity = 0.3f;
    private float startTime;

    private float startDragHorizontal;
    public Transform toggleList;

    void Start()
    {
        rect = transform.GetComponent<ScrollRect>();
        var _rectWidth = GetComponent<RectTransform>();
        var tempWidth = ((float)content.transform.childCount * _rectWidth.rect.width);
        content.sizeDelta = new Vector2(tempWidth, _rectWidth.rect.height);

        //未显示的长度
        float horizontalLength = content.rect.width - _rectWidth.rect.width;
        for (int i = 0; i < rect.content.transform.childCount; i++)
        {
            posList.Add(_rectWidth.rect.width * i / horizontalLength);
        }
    }

    void Update()
    {
        if (!isDrag && !stopMove)
        {
            startTime += Time.deltaTime;
            float t = startTime * smooting;

            float temp = Mathf.SmoothStep(0, 1, t);
            rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targethorizontal, temp);
            if (t >= 1)
                stopMove = true;
        }
    }

    public void ScrollToPage(int index, bool immediately = false)
    {
        if (index >= 0 && index < posList.Count)
        {
            if (immediately)
            {
                rect.horizontalNormalizedPosition = posList[index];
            }
            else
            {
                targethorizontal = posList[index]; //设置当前坐标,更新函数进行插值  
                isDrag = false;
                startTime = 0;
                stopMove = false;
            }

            SetPageIndex(index);
        }
    }

    public int GetPageCount()
    {
        return posList.Count;
    }

    private void SetPageIndex(int index)
    {
        if (currentPageIndex != index)
        {
            currentPageIndex = index;
            if (OnPageChanged != null)
                OnPageChanged(index);
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        isDrag = true;
        //开始拖动
        startDragHorizontal = rect.horizontalNormalizedPosition;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        float posX = rect.horizontalNormalizedPosition;
        posX += ((posX - startDragHorizontal) * sensitivity);
        posX = posX < 1 ? posX : 1;
        posX = posX > 0 ? posX : 0;
        int index = 0;
        float offset = Mathf.Abs(posList[index] - posX);

        for (int i = 1; i < posList.Count; i++)
        {
            float temp = Mathf.Abs(posList[i] - posX);
            if (temp < offset)
            {
                index = i;
                offset = temp;
            }
        }
        SetPageIndex(index);
        targethorizontal = posList[index]; //设置当前坐标,更新函数进行插值  
        isDrag = false;
        startTime = 0;
        stopMove = false;
    }

}

 onLeft和onRight绑定左右翻页按钮事件

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System;

public class GameController : MonoBehaviour
{
    //[SerializeField]
    //private Text pageNumber;
    //[SerializeField]
    //private InputField inputField;
    //[SerializeField]
    private PageView pageView;

    private int curPage = -1;

    
    void Start()
    {
        //pageNumber.text = string.Format("当前页码:0,总共页数: {0}", pageView.GetPageCount());
        //pageView.OnPageChanged = pageChanged;

        //pageView.ScrollToPage(0, true);
    }

    void pageChanged(int index)
    {
        //pageNumber.text = string.Format("当前页码:{0}, 总共页数: {1}", index.ToString(), pageView.GetPageCount());
        //curPage = index;
    }
    
   //翻到某页
    public void SetPageIndex(int index)
    {
        pageView.ScrollToPage(index);
    }
    public void onClick()
    {
        //try
        //{
        //    int idnex = int.Parse(inputField.text);
        //    pageView.ScrollToPage(idnex);
        //}
        //catch (Exception ex)
        //{
        //    Debug.LogWarning("请输入数字" + ex.ToString());
        //}
    }

    void Destroy()
    {
        pageView.OnPageChanged = null;
    }

    public void onLeftClick()
    {
        curPage--;
        if(curPage < 0) curPage = 0;
        pageView.ScrollToPage(curPage);
    }

    public void onRightClick()
    {
        curPage++;
        if(curPage >= pageView.GetPageCount()) curPage = pageView.GetPageCount()-1;
        pageView.ScrollToPage(curPage);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值