思路:
1 计算图片从一张移动到第二张的距离==图片的大小+图片之间的间距
2 获取content的X的位置
3 计算滑动时的的图片的index(图片放大的index)=X/距离
4 位置之间的平滑用Dotween处理
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class LeftAndRightInfiniteImageSroll: 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 = 100; //图片的大小
public float leftLimitXOffset = 200;
public float imageMoveDuration = 0.2f; //图片自动归为的时间
public float imageMaxSize = 1.2f;
public float imageMinSize = 0.8f;
public int indeximage; //当前图片的索引
private int imageSizeIndex; //图片变大的索引
[Header("显示图片index")] public string ImageShowIndexText = "ShowImageID";
[HideInInspector] private int count = 20; //显示显示的个数
private void Awake()
{
InitCompent();
}
void Start()
{
InitContentList();
Invoke("EnablEdcompent", .1f);
}
private void Update()
{
ImageAutoPos(imageSizeIndex);
}
//克隆
public void InitContentList()
{
foreach (RectTransform rectTransform in content)
{
//显示index
rectTransform.transform.Find(ImageShowIndexText).GetComponent<Text>().text = ShowImageList.Count + "";
rectTransform.localScale = new Vector3(imageMinSize, imageMinSize,imageMinSize);
SetImageSize();
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)
{
computeIndex();
SetImageSize();
// 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+ leftLimitXOffset <= scrollRectLeft)
{
ShowImageList[0].transform.SetAsLastSibling();
ShowImageList[0].anchoredPosition =
new Vector3(ShowImageList[ShowImageList.Count - 1].anchoredPosition.x + horizontalLayoutGroup.spacing + imgeSize, ShowImageList[0].anchoredPosition.y, 0);
ShowText(0, indeximage);
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--;
ShowText(ShowImageList.Count - 1, indeximage - ShowImageList.Count);
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;
}
/// <summary>
/// 显示文字
/// </summary>
/// <param name="imageIndex"></param>
/// <param name="ShowIndex"></param>
public virtual void ShowText(int imageIndex, int ShowIndex)
{
ShowImageList[imageIndex].Find(ImageShowIndexText).GetComponent<Text>().text = ShowIndex + "";
}
/// <summary>
/// 计算图片变大的index
/// </summary>
private void computeIndex()
{
imageSizeIndex = Mathf.RoundToInt(content.anchoredPosition.x / -(imgeSize + horizontalLayoutGroup.spacing));
// Debug.Log("图片变大:"+ imageSizeIndex+"Content.X:"+ content.anchoredPosition.x);
}
/// <summary>
/// 设置图片的属性
/// </summary>
/// <param name="imageIndex">(无限滚动的)图片的索引</param>
private void SetImageSize()
{
for (int i = 0; i < ShowImageList.Count; i++)
{
if (ShowImageList[i].transform.Find(ImageShowIndexText).GetComponent<Text>().text==imageSizeIndex.ToString())
{
ShowImageList[i].localScale = new Vector2(imageMaxSize, imageMaxSize);
}
else
{
ShowImageList[i].localScale = new Vector2(imageMinSize, imageMinSize);
}
}
}
/// <summary>
/// 图片自动归位
/// </summary>
/// <param name="ShowTextIndex">显示当前图片的索引</param>
private void ImageAutoPos(int ShowTextIndex)
{
if (Input.GetMouseButtonUp(0))
{
content.transform.DOLocalMoveX(-imageSizeIndex *(imgeSize + horizontalLayoutGroup.spacing), imageMoveDuration);
}
}
private void OnDisable()
{
indeximage = 0;
if (horizontalLayoutGroup != null)
horizontalLayoutGroup.enabled = true;
if (contentSizeFitter != null)
contentSizeFitter.enabled = true;
}
}