基于ScrollRect实现翻页效果

前言

unity提供的ScrollRect组件可以实现左右或者上下滑动效果,翻页效果则需要滑动结束后锁定到某一页。只需要根据拖动结束时,获取ScrollRect的content移动的方向以及移动的目标位置即可。

1.使用接口

要获取鼠标(或者点击)开始结束时讯息(包括开始拖动时的事件以及对应的坐标),unity为我们提供了两个接口来实现相关方法之前在Unity基础命令中也提到过。两个接口对应两个方法,即可以对应开始结束拖动时的事件,数据则为eventData中。

 public void OnBeginDrag(PointerEventData eventData)
public void OnEndDrag(PointerEventData eventData)

2.使用相对位置方法

public class NewMove : MonoBehaviour,IBeginDragHandler,IEndDragHandler {

    private ScrollRect scrollRect;
    public Toggle[] toggleArr;
    //存储特定的位置坐标
    private float[] pageArr=new float[]{0,0.5f,1.0f};
    public void OnBeginDrag(PointerEventData eventData)
    {
       // Debug.Log("Begin:");
       // Debug.Log(eventData.position);
       //获取rect的初始坐标值
        Vector2 pos = scrollRect.normalizedPosition;
        Debug.Log("Begin:"+pos);
    }
    public void OnEndDrag(PointerEventData eventData)
    {
        //Debug.Log("End:");
        //Debug.Log(eventData.position);
        //获取rect的拖动后的坐标值
        Vector2 pos = scrollRect.normalizedPosition;
        Debug.Log("End:"+pos);
        //获取rect拖动后的水平坐标值
        float posX = scrollRect.horizontalNormalizedPosition;
        int index = 0;
        //计算与特定点的偏差
        float offset = Math.Abs(pageArr[index] - posX);
        //与每一个坐标点进行比较,确定应该存在的位置
        //偏差最小的位置即为rect的位置点
        for(int i=0;i<pageArr.Length;i++)
        {
            float newOffset = Math.Abs(pageArr[i] - posX);
            if(newOffset<= offset)
            {
                index = i;
                offset = newOffset;
            }
        }
        scrollRect.horizontalNormalizedPosition = pageArr[index];
        toggleArr[index].isOn = true;
        Debug.Log("End:" + scrollRect.horizontalNormalizedPosition);
    }

3.使用绝对位置

此脚本使用绝对位置计算目标位置,并在Update中更新位置,实现平滑移动。

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

public class DragController : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    [SerializeField]
    private GameObject scrollRect;
    [SerializeField]
    private GameObject scrollRectSmall;

    public float distance = 600f;
    public int smoothing = 2;
    public float deltaWidth = 3840f;
    public float deltaSmallWidth = 95f;

    private List<GameObject> pages;
    private List<GameObject> smallScreens;
    private float horizontalPos = 0;
    private float horizontalPosSmall = 0;
    private List<float> postions = new List<float>();

    private bool onDrag = false;
    private float beginPos = 0; 
    private float endPos = 0;
    private int pageIndex = 0;


    public void Init(List<GameObject> pages)
    {
        this.pages = new List<GameObject>(pages);
        //this.smallScreens = smallScreens;
        pageIndex = 0;
        horizontalPos = 0;
        horizontalPosSmall = 0;
        //for (int i=0;i<pages.Count;i++)
        //{
        //    postions.Add(i);
        //}
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        onDrag = true;
        beginPos = eventData.position.x;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        onDrag = false;
        endPos = eventData.position.x;
        float newDis = endPos - beginPos;

        if (newDis < -distance)
        {
            pageIndex++;
            if (pageIndex >= pages.Count)
            {
                pageIndex = pages.Count - 1;
            }            
        }    
        if(newDis > distance)
        {
            pageIndex--;
            if(pageIndex < 0)
            {
                pageIndex = 0;
            }
        }
        horizontalPos = -deltaWidth * pageIndex;
        //print(horizontalPos);
        horizontalPosSmall = -deltaSmallWidth * pageIndex;
        //print(horizontalPosSmall);
        pages[pageIndex].GetComponent<Toggle>().isOn = true;
        //smallScreens[pageIndex].GetComponent<Toggle>().isOn = true;
    }    

    // Use this for initialization
    void Start () {
        float scale = 3840f / Screen.width;
        deltaWidth = deltaWidth / scale;
    }

    // Update is called once per frame
    void Update () {
        if (!onDrag)
        {
            //scrollRect.GetComponent<rec = Mathf.Lerp(scrollRect.horizontalNormalizedPosition,
            //           horizontalPos, smoothing * Time.deltaTime);
            Vector2 pos = scrollRect.GetComponent<RectTransform>().position;
            float xPos = Mathf.Lerp(pos.x, horizontalPos, Time.deltaTime * smoothing);
            scrollRect.GetComponent<RectTransform>().position = new Vector2(xPos, pos.y);
            //print(xPos + " " + horizontalPos);

            //Vector2 posS = scrollRectSmall.GetComponent<RectTransform>().anchoredPosition;
            //float xPosS = Mathf.Lerp(posS.x, horizontalPosSmall, Time.deltaTime * smoothing);            
            //scrollRectSmall.GetComponent<RectTransform>().anchoredPosition = new Vector2(xPosS, posS.y);
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值