美文网首页
unity UGUI滑动菜单栏吸附效果

unity UGUI滑动菜单栏吸附效果

作者: WOTTOW | 来源:发表于2020-01-02 20:38 被阅读0次

    思路:
    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

    相关文章

      网友评论

          本文标题:unity UGUI滑动菜单栏吸附效果

          本文链接:https://www.haomeiwen.com/subject/fjtooctx.html