前言
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);
}
}
}