unity UGUI滑动菜单栏吸附效果

思路:
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;
    }
}
image.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 生活总归不易,看我们用什么样的心态去面对。 感觉已经持续有一段时间,整个人处于低谷状态,具体不知道因为什么。因为工...
    刘云杰阅读 341评论 0 0
  • 这不过是秋季,自然的萧条和蛰伏,街道上只剩下微风。一年一年亦是如此,人们还记得自己伙伴和仇人的样子。一年一年亦是如...
    何老蔡阅读 250评论 0 0
  • 垃圾,只是放错了位置的宝。 ————前言 错误一 ——要么在沉默中爆发,要么在沉默中死亡。 沉默,是一个人的喧嚣;...
    陈贰九阅读 884评论 0 11
  • 到北京啦! 这次的时间特别gang其实空气我特喜欢,我觉得很舒服!虽然有点干燥,但特别的干净!还有厕所是我喜欢的宽...
    厦门整理师张桂华阅读 101评论 0 0
  • 虞美人•春风 烟云逐影瑶台舞,一水堪留住?柳丝轻剪称心怀,犹是裹香向晚,染桃腮。 呢侬对燕和庭树,也与春花叙。画堂...
    水兰_93bf阅读 202评论 0 4