UGUI 水平滚动翻页 简单步骤版 超详细

(学习网上公开教程的笔记和小思考)

1.创建一个空gameobject,可以命名为:scroll rect

(手动设置width和height作为列表显示滚动的区域)

2.把一长串的grid 放到里面

3.在 scroll rect 上面添加 scroll rect  组件,和image组件,两者必须齐全,缺一不可(因为 image有射线检测组件,才可以在运行时候检测到点击拖动等事件)

组件里面的content即为可滚动列表区域,把grid放入

滚动是按照超出范围进行控制的,因此会在scroll rect 框定范围左右进行移动

在scroll rect上可以取消勾选vertical或者horizontal来控制滑动方向

4.继续在scroll rect组件上 添加mask来控制显示范围,超出区域的不显示,mask!!!!!很重要,mask也能控制子物体的显示程度,跟image相关,所以上面image透明度不能设置为0,否则会看不见子物体滚动内容。

mask作用:超出范围部分不显示,遮罩作用

5.想要切换页面,需要监测滚动判断离哪一页更近

(1)使用scroll rect监听滚动值,滚动到末尾的时候会传入1(传的是二维向量,左右是X值)

拖拽结束之后离哪一页更近,到哪一页

(2)滚动到指定页代码

首先测试返回值

(超出范围监听到的是1.1,正常到结束末尾,坐标是1)

(3)实现拖拽接口

只要继承这两个接口就会监听    开始拖拽事件  和    结束拖拽事件

不需要使用on value change 去指定,会自动触发, 但必须和scroll rect作用的游戏物体,处于同一界面

(4)定义一个scroll

属性:

normalize Position 可以把位置设置为0-1 范围区间,拿到scroll的值,进行量化操作,例如获取值和设置值。

(5)想要进行页面跳转首先要进行页面位置的判定

把四个页面进,0-1的平均分,拿到每个页面中间数值,例如三个页面是0,0.5f ,1

通过scroll拿到当前页面的位置,判断离哪一个页面更近,然后设置成那个页面的位置,即为跳转

(6)通过for循环不断判断,当前位置和不同页面之间的偏移,选择偏移量最小的就是距离最近的页面。

(7)设置了最近的页面,直接跳转比较突兀,可以物理增加一个缓动效果

通过慢慢增加targetposition来实现,ismoving 在updated里进行控制,动画判断

把最后赋值给的改成targetPosition

然后进行mini动画

动画方法就一行,但是做完之后要进行判断,是否到目标页面,到了就停止动画并且把目标位置给他。

(8)通过按钮选择进行控制页面切换

toggle被选中都会触发on value change, 改变的是bool值,触发是true,不触发是false

逻辑比较简单,但是要在每个toggle进行onvaluechange传入设置。

可以封装成下面的代码:

public void MoveToPage(int pageIndex, bool isOn)
{
    if (isOn && pageIndex >= 0 && pageIndex < pagePosition.Length)
    {
        isMoving = true;
        targetPosition = pagePosition[pageIndex];
    }
}

最后,案例的总体代码如下:

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

public class LevelScrollRect : MonoBehaviour,IBeginDragHandler,IEndDragHandler
{
    private ScrollRect scroll;

    private float[] pagePosition = new float[4] { 0,0.3333f,0.6666f, 1 };

    public Toggle[] toggleArray;

    private float targetPosition = 0;
    private bool isMoving = false;
    private float speed = 7;

    // Start is called before the first frame update
    void Start()
    {
        scroll = GetComponent<ScrollRect>();
    }

    // Update is called once per frame
    void Update()
    {
        if (isMoving)
        {
            scroll.horizontalNormalizedPosition = 
                Mathf.Lerp(scroll.horizontalNormalizedPosition, targetPosition, Time.deltaTime*speed);
            if( Mathf.Abs(scroll.horizontalNormalizedPosition - targetPosition)<0.001f)
            {
                isMoving = false;
                scroll.horizontalNormalizedPosition = targetPosition;
            }
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        float currentPosition = scroll.horizontalNormalizedPosition;
        int index = 0;
        float offset = currentPosition - pagePosition[0];
        for(int i=1;i<4;i++)
        {
            if( Mathf.Abs(currentPosition-pagePosition[i]) < offset)
            {
                index = i;
                offset = Mathf.Abs(currentPosition - pagePosition[i]);
            }
        }

        targetPosition=pagePosition[index];
        isMoving = true;
        toggleArray[index].isOn = true;
    }

    public void MoveToPage1(bool isOn)
    {
        if (isOn)
        {
            isMoving = true;
            targetPosition = pagePosition[0];
        }
    }
    public void MoveToPage2(bool isOn)
    {
        if (isOn)
        {
            isMoving = true;
            targetPosition = pagePosition[1];
        }
    }
    public void MoveToPage3(bool isOn)
    {
        if (isOn)
        {
            isMoving = true;
            targetPosition = pagePosition[2];
        }
    }
    public void MoveToPage4(bool isOn)
    {
        if (isOn)
        {
            isMoving = true;
            targetPosition = pagePosition[3];
        }
    }

}

我在具体项目中借鉴使用的代码如下:

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

public class LevelScrollRect : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    private ScrollRect scroll;
    private float[] pagePosition = new float[3] { 0, 0.5f, 1 };
    public Toggle[] toggleArray;
    private float targetPosition = 0;
    private bool isMoving = false;
    private float speed = 7;

    void Start()
    {
        scroll = GetComponent<ScrollRect>();
        targetPosition = scroll.horizontalNormalizedPosition;
        
        for (int i = 0; i < toggleArray.Length; i++)
        {
            int index = i;
            toggleArray[i].onValueChanged.AddListener((isOn) => MoveToPage(index, isOn));
        }
    }

    void Update()
    {
        moving();
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        ChangePage();
    }

    public void moving()
    {
        if (isMoving)
        {
            scroll.horizontalNormalizedPosition =
                Mathf.Lerp(scroll.horizontalNormalizedPosition, targetPosition, Time.deltaTime * speed);
            if (Mathf.Abs(scroll.horizontalNormalizedPosition - targetPosition) < 0.001f)
            {
                isMoving = false;
                scroll.horizontalNormalizedPosition = targetPosition;
            }
        }
    }

    public void ChangePage()
    {
        float currentPosition = scroll.horizontalNormalizedPosition;
        int index = 0;
        float minOffset = Mathf.Abs(currentPosition - pagePosition[0]);
        for (int i = 1; i < pagePosition.Length; i++)
        {
            float offset = Mathf.Abs(currentPosition - pagePosition[i]);
            if (offset < minOffset)
            {
                index = i;
                minOffset = offset;
            }
        }

        targetPosition = pagePosition[index];
        isMoving = true;
        toggleArray[index].isOn = true;
    }
    
    //toggle 为true调用下面的方法,记得面板设置一下
    public void MoveToPage(int pageIndex, bool isOn)
    {
        if (isOn && pageIndex >= 0 && pageIndex < pagePosition.Length)
        {
            isMoving = true;
            targetPosition = pagePosition[pageIndex];
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值