unity无限滚动循环翻页的pageview

因为业务需求需要做一个循环的列表,无限循环,

而unity自带的scrollview不满足循环的要求,所以就自定义了一个控件

控件结构如下:

unity无限滚动循环翻页的pageview_第1张图片

下面是写的代码代码里的注释包含我的思路,以及优化方案

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

namespace MocoDog
{
    public class pageView : UIWindowBase
    {
        // Start is called before the first frame update
        public GameObject content;//父控件
        public GameObject preItem;  //cell

        public GameObject btnLeft;//父控件
        public GameObject btnRight;//父控件
        private float posx = 0;//初始位置
        private float cellSize = 0;//每次移动的距离
        private float maxPosX = 0;//当前最大位置X
        private float minPosX = 0;//当前最小位置

        private List itemList;//item存储容器

        void Start()
        {
            this.RegisterEvent(btnLeft, OnClickBtnLeft);
            this.RegisterEvent(btnRight, OnClickBtnRight);
         
            preItem.SetActive(false);
            var rt = preItem.GetComponent();
            cellSize = rt.sizeDelta.x + 30;
            Debug.Log("====cellSize: " + cellSize);
            // var rt1 = content.GetComponent();
            // posx = rt1.anchoredPosition.x;
            // Debug.Log("====rt1.posx: " + posx);
            InitItemList();
        }
        void InitItemList()
        {
            itemList = new List();
            for (int i = 0; i < 10; i++)
            {
                GameObject obj = GameObject.Instantiate(preItem);
                obj.transform.SetParent(content.GetComponent());
                if (i == 9)
                {
                    obj.transform.localPosition = new Vector3(cellSize * -1,-200,0);
                    minPosX = cellSize * -1;
                }
                else
                {
                    obj.transform.localPosition = new Vector3(cellSize * i,-200,0);
                    maxPosX = cellSize * i;
                }
                obj.transform.Find("bg_count/Text").GetComponent().text = i.ToString();
                obj.transform.localScale = Vector3.one;
                if (!obj.activeSelf)
                    obj.SetActive(true);
                //添加元素到数组中
                itemList.Add(obj);
            }
            ListSort();
        }
        void OnClickBtnLeft(GameObject objname)
        { 
            posx = posx - cellSize;
            Debug.Log("====posx: " + posx);
            content.transform.DOLocalMoveX(posx, 0.4f);
            //
            var obj2 = itemList[4];
            ani2(obj2);
            var obj1 = itemList[1];
            ani1(obj1);
            //移动第一个子节点到最后面
            var obj = itemList[0];
            maxPosX = maxPosX + cellSize;
            minPosX = minPosX + cellSize;
            obj.transform.localPosition = new Vector3(maxPosX,-200,0);
            ListSort();
        }

        void OnClickBtnRight(GameObject objname)
        {
            posx = posx + cellSize;
            Debug.Log("====posx: " + posx);
            content.transform.DOLocalMoveX(posx, 0.4f);
            var obj1 = itemList[3];
            ani1(obj1);
            var obj2 = itemList[0];
            ani2(obj2);
            //移动一个子节点到最前面
            var obj = itemList[itemList.Count - 1];
            //改变obj的位置
            maxPosX = maxPosX - cellSize;
            minPosX = minPosX - cellSize;
            obj.transform.localPosition = new Vector3(minPosX,-200,0);
            //根据位置对List排序
            ListSort();
        }
        void ListSort()
        {
            itemList.Sort(
                delegate(GameObject p1,GameObject p2)
                {
                    return  p1.transform.localPosition.x.CompareTo( p2.transform.localPosition.x);//升序
                }
            );
            //做优化的话在这里将content位置归零然后遍历子节点更改位置 
            //可以用一个常量数组存储节点位置
            //同时重置最大坐标最小坐标
            //注意一定要在动作结束后执行
        }
        void ani1(GameObject obj)
        {
            RectTransform rectx = obj.GetComponent();
            Sequence mySequence = DOTween.Sequence();
            mySequence.Append(rectx.DOScale(0.8f, 0.2f).SetEase(Ease.InSine));
            // mySequence.Append(rectx.DOScale(Vector3.one, 0.1f).OnComplete(() =>
            // {
            //     //动画完成
            // }));

        }
        void ani2(GameObject obj)
        {
            RectTransform rectx = obj.GetComponent();
            Sequence mySequence = DOTween.Sequence();
            mySequence.Append(rectx.DOScale(1.2f, 0.2f).SetEase(Ease.InSine));
            mySequence.Append(rectx.DOScale(Vector3.one, 0.1f).OnComplete(() =>
            {
                //动画完成
            }));

        }
        // Update is called once per frame
        void Update()
        {
            
        }
    }
}

不足之处,由于是不停的移动content的位置,如果用户闲得无聊一直一个方向点击时间过长的话,有可能会出现posx超界的情况,所以可以在移动结束的时候将content的位置归零,然后遍历子节点更改位置,这部分代码我就不放出来了

源码地址:https://download.csdn.net/download/panadalove/12517268

你可能感兴趣的:(unity)