在unity中实现分页滚动的效果和吸附功能(UGUI)

Posted 头号理想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在unity中实现分页滚动的效果和吸附功能(UGUI)相关的知识,希望对你有一定的参考价值。

在不少游戏中都会有自动滚动的效果
我们这里用UGUI的Scroll View来实现一下
我建议大家在开始做之前 首先先了解一下这个的基本用法
我之前也没写过关于这个的使用方法

然后先给大家一个效果图片(里边的水印大家凑活看一下)

可以看到 当我们鼠标不移上去的时候 他是自己滚动的 当我们自己鼠标移动上去并且拖拽的时候
他可以被我们拖动 而且 通过代码自动检测区域 然后吸附过去

实现过程

首先我们现在unity中搭建所要的Scrool View

content上的组件
之后就是代码了 其中计算比较麻烦 仔细看看其实也不是特别复杂

public class PageScrollview : MonoBehaviour,IEndDragHandler,IBeginDragHandler

    #region 声明对象
    public enum ScrolType
    
        //滑动类型(分为两种 横纵两种)
        HorizontalType,
        VerticalType
    

    ScrollRect rect;
    private int pagecount;//选项个数

    private RectTransform content;
    private   float[] pages;//位置

    [Header("滚动参数")]
    public float movetime = 0.3f;//移动的时间
    public float timer = 0;//计时器
    public float startmovepos;//开始移动的位置
    public int currentindex = 0;//当前所处页数
    private bool ismoving = false;

    private bool isDraging = false;//是否在拖动中


    [Header("自动滚动参数")]
    public  bool isAutoScrol=true ;//是否自动滚动
    public float AutoTime = 2f;//自动滚动时间间隔
    public float autotimer = 0;//自动计时器

    [Header("滑动类型")]
    public ScrolType scroltype = ScrolType.HorizontalType;
    #endregion
    private void Start()
    
        Init();//初始化
    
   
    private void Update()
    
        listenermove();
        listenerAutoScroll();
    


    private void Init()
    
        rect = GetComponent<ScrollRect>();
        if (rect == null)
        
            Debug.LogError("不存在组件ScrollRect");

        
        content = GameObject.Find("Content").GetComponent<RectTransform>();
        pagecount = content.childCount;//子节点数量
        pages = new float[pagecount];//初始化

        if (pages.Length == 1)
        
            Debug.LogError("只有一页 不用滚动");
        
        for (int i = 0; i < pages.Length; i++)
        

            switch (scroltype)
            
                case ScrolType.HorizontalType:
                    pages[i] = i * (1.0f / (float)(pagecount - 1));//给位置的数组赋值
                    break;
                case ScrolType.VerticalType:
                    pages[i] = 1 - i * (1.0f / (float)(pagecount - 1));//给位置的数组赋值
                    break;
            
        
    

    private  void listenermove()//监听滑动
    
        if (ismoving)
        
            timer += Time.deltaTime * movetime;
           
            //灵魂就在这里
            switch (scroltype)
            
                case ScrolType.HorizontalType:
                    rect.horizontalNormalizedPosition = Mathf.Lerp(startmovepos, pages[currentindex], timer);
                    break;
                case ScrolType.VerticalType:
                    rect.verticalNormalizedPosition = Mathf.Lerp(startmovepos, pages[currentindex], timer);
                    break;
            

            if (timer >= 1)
            
                ismoving = false;
            
        
    

    private void listenerAutoScroll()//自动滑动
    
        if (isDraging)
        
            return;
        
        if (isAutoScrol)
        
            autotimer += Time.deltaTime;
            if (autotimer > AutoTime)
            
                autotimer = 0;
                currentindex++;
                currentindex %= pagecount;//取余形成循环
                scrolltopage(currentindex);
            
        
    

    private void scrolltopage(int page)
    
        ismoving = true;
        this.currentindex = page;
        timer = 0;
       

        switch (scroltype)
        
            case ScrolType.HorizontalType:
                startmovepos = rect.horizontalNormalizedPosition;
                break;
            case ScrolType.VerticalType:
                startmovepos = rect.verticalNormalizedPosition;
                break;
        
    

    //取消拖动的接口
    public void OnEndDrag(PointerEventData eventData)
    
        int min = 0;
        //计算当最近的一页是哪个
       for(int i = 0; i < pages.Length; i++)
        
            switch (scroltype)
            
                case ScrolType.HorizontalType:
                    if (Mathf.Abs(pages[i] - rect.horizontalNormalizedPosition) < Mathf.Abs(pages[min] - rect.horizontalNormalizedPosition))
                    
                        min = i;
                    
                    break;
                case ScrolType.VerticalType:
                    if (Mathf.Abs(pages[i] - rect.verticalNormalizedPosition) < Mathf.Abs(pages[min] - rect.verticalNormalizedPosition))
                    
                        min = i;
                    
                    break;
            
        
        scrolltopage(min);
        isDraging = false;
        autotimer = 0;
    


    //开始拖动的接口
    public void OnBeginDrag(PointerEventData eventData)
    
        isDraging = true;
    

里边使用了一个枚举 使用来方便数轴上的修改的

希望这篇博文对你有所帮助
如果有问题或者是合作 主页有我的联系方式(知无不答)

之后我还会持续更新这个方面的内容

以上是关于在unity中实现分页滚动的效果和吸附功能(UGUI)的主要内容,如果未能解决你的问题,请参考以下文章

在unity中实现分页扩展(旋转3D)功能(UGUI)

如何在 Xamarin 表单中实现分页

在SSH项目中实现分页效果

如何在 React 中实现分页

小案例--面向对象中实现分页

在ssh中实现分页排序