unity UGUI无限滚动

2019-11-03  本文已影响0人  WOTTOW

在开始时,我们需要理解在UI中RectTransform中的Pivot。
Pivot相当与一张图片的中心点
例如:


image.png

图片位置的轴是以Pivot作为轴的中心,来计算当前图片的位置信息。


image.png

了解pivot的轴心的位置便于我们设置滑动UI的边界
pivot(0,0)


image.png

pivot(1,0)


image.png
pivot(1,1)
image.png
pivot(0,1)
image.png

这里以左右无限滑动作为例子
在明白pivot的作用后,我们需要设置左边、右边的边界(边界:当图片到达边界时自动移动位置)

边界

image.png
首页需要把这些对象的pivot设置为(0,0)
左边界:
LimitLeft=scrollRect.transform.TransformPoint(Vector3.zero).x;
获取左边的滚动矩形的最左边的位置
往左边滑动
方法一: cueerntImageLeft=获取最左边的图片的锚点的X轴+图片与图片的间距
方法二:Vector3 X=new Vector3 (获取最左边的图片的局部坐标+ImgeSize,0,0);
cueerntImageLeft=ScrollRect.transform.TransformPoint(X).x;
if(LimitLeft=>cueerntImageLeft)
{
图片排序一次,
把最左边的图片替换把右边
}

右边界:
Vector3 scrollRectAnchorRight = new Vector3 (获取scrollRect的宽度+图片与图片的间距);
LimitRight=scrollRect.transform.TransformPoint(scrollRectAnchorRight )
.x;
往右边滑动:
根据左边的一样同理,只不过这次获取的是最右边的图片
if(LimitRight<=cueerntImageRight)
{
图片排序一次,
把最右边的图片替换把左边
}

这里需要了解 父级.transform.TransformPoint:
在官方的解释中:局部左边转换为世界坐标

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

public class Test : MonoBehaviour
{
    public RectTransform content;   //滑动内容
    public ScrollRect scrollRect;

    private ContentSizeFitter contentSizeFitter;
    private HorizontalLayoutGroup horizontalLayoutGroup;

    private List<RectTransform> ShowImageList = new List<RectTransform>();     //存储循环显示的Image
    private RectTransform scrollRectTransform;

    private float Startpoitios;     //记录开始的位置     
    private float curretPosition;   //当前的位置信息
    private float scrollRectLeft;   //滑动的参照点
    private float ImgeSize = 300;   //图片的大小
    public int indeximage;         //UI的ID

    [HideInInspector] private int count = 20;  //显示显示的个数

    private void Awake()
    {
        InitCompent();
    }

    void Start()
    {
        InitContentList();
        Invoke("EnablEdcompent", .1f);
    }

    //克隆
    public void InitContentList()
    {
        foreach (RectTransform rectTransform in content)
        {
            indeximage++;
            ShowImageList.Add(rectTransform);
        }
    }

    public void InitCompent()
    {
        contentSizeFitter = content.GetComponent<ContentSizeFitter>();
        horizontalLayoutGroup = content.GetComponent<HorizontalLayoutGroup>();
        scrollRect = scrollRect.GetComponent<ScrollRect>();
        //左边的边界
         scrollRectLeft = scrollRect.transform.TransformPoint(Vector3.zero).x;
        //  scrollRectLeft = scrollRectTransform.anchoredPosition.x;
        scrollRectTransform = scrollRect.GetComponent<RectTransform>();
     
        scrollRect.onValueChanged.AddListener((data) => { infiniteScroll(data); });
    }

    public void EnablEdcompent()
    {
        horizontalLayoutGroup.enabled = false;
        contentSizeFitter.enabled = false;
    }

    //无限滑动
    public void infiniteScroll(Vector2 data)
    {
        //  float Left = content.transform.TransformPoint(ShowImageList[0].localPosition.x + ImgeSize, ShowImageList[0].localPosition.y, 0).x;
        float Left = ShowImageList[0].position.x + ImgeSize;
        curretPosition = content.GetComponent<RectTransform>().anchoredPosition.x;
        float offsetX = curretPosition - Startpoitios;

        if (offsetX < 0)
        {
            if (indeximage + 1 <= count)
            {
                Startpoitios = curretPosition;
                Debug.LogError("A:"+ (Left + ImgeSize)+"B:"+ scrollRectLeft);
                if (Left + ImgeSize <= scrollRectLeft)
                {
                    ShowImageList[0].transform.SetAsLastSibling();
                    ShowImageList[0].anchoredPosition =
                    new Vector3(ShowImageList[ShowImageList.Count - 1].anchoredPosition.x + horizontalLayoutGroup.spacing + ImgeSize, ShowImageList[0].anchoredPosition.y, 0);
                    indeximage++;
                    for (int i = 0; i < ShowImageList.Count; i++)
                    {
                        ShowImageList[i] = content.transform.GetChild(i).GetComponent<RectTransform>();
                    }
                    content.GetComponent<RectTransform>().sizeDelta += new Vector2(horizontalLayoutGroup.spacing + ImgeSize, 0);
                }
            }
        }
        else
        {
            //   Vector3 scrollRectAnchorRight = new Vector3(scrollRectTransform.rect.width + horizontalLayoutGroup.spacing, 0, 0f);
            //float scrollRectRight = scrollRect.transform.TransformPoint(scrollRectAnchorRight).x;
             float scrollRectRight = scrollRectLeft + scrollRectTransform.rect.width + horizontalLayoutGroup.spacing;
            Vector3 childUpRight = new Vector3(ShowImageList[ShowImageList.Count - 1].anchoredPosition.x, ShowImageList[ShowImageList.Count - 1].anchoredPosition.y, 0f);
            float childRight = content.transform.TransformPoint(childUpRight).x;
            if (childRight >= scrollRectRight + ImgeSize)
            {
                if (indeximage - ShowImageList.Count == 0)
                {
                    return;
                }
                ShowImageList[ShowImageList.Count - 1].SetAsFirstSibling();
                indeximage--;
                ShowImageList[ShowImageList.Count - 1].anchoredPosition = new Vector2(ShowImageList[0].anchoredPosition.x - horizontalLayoutGroup.spacing - ImgeSize, ShowImageList[ShowImageList.Count - 1].anchoredPosition.y);
                for (int i = 0; i < ShowImageList.Count; i++)
                {
                    ShowImageList[i] = content.transform.GetChild(i).GetComponent<RectTransform>();
                }
                content.GetComponent<RectTransform>().sizeDelta -= new Vector2(horizontalLayoutGroup.spacing + ImgeSize, 0);
            }
        }
        Startpoitios = curretPosition;
    }

    private void OnDisable()
    {
        indeximage = 0;
        if(horizontalLayoutGroup!=null)
        horizontalLayoutGroup.enabled = true;
        if(contentSizeFitter!=null)
        contentSizeFitter.enabled = true;
    }
}

Image.gif
上一篇下一篇

猜你喜欢

热点阅读