Unity之滑页效果&基于ScrollRect实现

Posted 彩色墨水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity之滑页效果&基于ScrollRect实现相关的知识,希望对你有一定的参考价值。

Unity之滑页效果&基于ScrollRect实现

效果图

设计思路

  1. 基于ScrollRect的基础功能,本身在ScrollRect下的Content内容就是可以滑动的,但是它的滑动不符合预期
  2. 我们把滑动的效果设置为预期效果,那就需要获得开始滑动,滑动中,滑动结束的函数进行改造
  3. 我们在开始滑动记录位置,滑动中的幅度值,滑动结束记录位置,然后滑动结束时控制滑动效果
  4. 达到下一页的阈值,计算好下一页的位置,那就让页面Lerp插值到指定位置,滑动结束

场景搭建

创建一个scrollRect,替换ScrollRect脚本,使用我们自己的脚本ScrollRectBase,该脚本继承了ScrollRect,对其中一些关键方法进行了重写,并暴露一些关键事件给外界注册。

在Content下创建我们的页面,页面数量自定义,我这里创了5个页面。
创建一个导航栏,用来指示我当前所滑到的页面位置。

代码


    #region 重构拖拽相关的逻辑  
    //ScrollRect里面就带有滑动相关的特性,拖拽时Content里面的内容就是会动的,我要做的是在拖拽结束时执行自己想要的效果,而不是它自带的效果,就是在拖拽结束时快速切换到指定的页面,而不是缓动直至慢慢停止
    public override void OnBeginDrag(PointerEventData eventData)
    
        if (UseDrag)
        
            OnBeginDragInternal(eventData);
        
    

    public void OnBeginDragInternal(PointerEventData eventData)
    
        base.OnBeginDrag(eventData);
        if (UsePage)
        
            OnBeginDragPage(eventData);
        
    

    public override void OnDrag(PointerEventData eventData)
    
        if (UseDrag)
        
            OnDragInternal(eventData);
        
    

    public void OnDragInternal(PointerEventData eventData)
    
        base.OnDrag(eventData);
        if (UsePage)
        
            OnDragPage(eventData);
        
        if (Drag != null)
        
            Drag(eventData);
        
    

    public override void OnEndDrag(PointerEventData eventData)
    
        if (UseDrag)
        
            OnEndDragInternal(eventData);
        
    

    public void OnEndDragInternal(PointerEventData eventData)
    
        base.OnEndDrag(eventData);
        if (UsePage)
        
            OnEndDragPage(eventData);
        
    


    ///开始拖拽
    private void OnBeginDragPage(PointerEventData eventData)
    
        bDragging = true;
        BeginDragPos = eventData.position.x;
    

    //拖拽中
    private void OnDragPage(PointerEventData eventData)
    
        Debug.Log(eventData.delta);
        Vector2 delta = eventData.delta;
        speed = delta.x;
    

    //拖拽结束
    private void OnEndDragPage(PointerEventData eventData)
    
        EndDragPos = eventData.position.x;

        float LofR = BeginDragPos - EndDragPos;
        if (Mathf.Abs(speed) > SpeedCritical || Mathf.Abs(BeginDragPos - EndDragPos) > 400f)//能够切到下一页的阈值,一个是速度达到20,一个是滑动距离大于400
        
            if (LofR < 0f)
            
                currentPage = GetNextPage(currentPage, true);
            
            else
            
                currentPage = GetNextPage(currentPage, false);
            
            currentPage = Mathf.Clamp(currentPage, 0, Page_Count - 1);
        

        bUpdateEnd = false;
        bDragging = false;
        speed = 0f;
        BeginDragPos = 0;
        EndDragPos = 0;
        UpdateScrollEndPos();
        if (EndDragItem != null)
        
            EndDragItem(currentPage);
        
    

    //计算停止页面的位置
    private void UpdateScrollEndPos()
    
        scrollendpos = currentPage * (1f / ((float)Page_Count - 1));
    

    //更新页面
    private void OnUpdatePage()
    
        //拖拽过程中不更新页面
        if (bDragging || bSendFinish)
        
            return;
        
        if (base.horizontal)
        
            base.horizontalNormalizedPosition = Mathf.Lerp(base.horizontalNormalizedPosition, scrollendpos, 15f * Time.deltaTime);
            float num = Mathf.Abs(base.horizontalNormalizedPosition - scrollendpos);
            Vector2 sizeDelta = base.content.sizeDelta;
            if (num * sizeDelta.x < 2f)//最后距离不多了直接到位
            
                base.horizontalNormalizedPosition = scrollendpos;
                bUpdateEnd = true;
            
        
        if (bUpdateEnd)
        
            if (mPageAniFinish != null)
            
                mPageAniFinish();
            
            bSendFinish = true;
        
    

    private void Update()
    
        if (UsePage)
        
             OnUpdatePage();
        
    

工程项目

链接:https://pan.baidu.com/s/1zuNIDWQrjcWiEwBlU-yYbA
提取码:xhg8

以上是关于Unity之滑页效果&基于ScrollRect实现的主要内容,如果未能解决你的问题,请参考以下文章

Unity之滑页效果&基于ScrollRect实现

串口屏开发之滑块控件的使用总结——如何通过滑动滑块实现进度条和文本的联动效果

串口屏开发之滑块控件的使用总结——如何通过滑动滑块实现进度条和文本的联动效果

Swiper之滑块

登录校验之滑块验证码完整实现(vue + springboot)

Unity微信聊天框界面制作