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的作用后,我们需要设置左边、右边的边界(边界:当图片到达边界时自动移动位置)
边界
首页需要把这些对象的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