UGUI Scrollrect滚动优化:无限循环利用

1 功能描述

在做排行榜类似界面时,item非常多,可能有几百个,一次创建这么多GameObject是非常卡的。为此,使用只创建可视区一共显示的个数,加上后置准备个数。如图所示

UGUI Scrollrect滚动优化:无限循环利用_第1张图片

 

图中红色框是可视区,可视区一共可显示4个item,后置准备1个item.当向左滑,0号滑出可视区,4号进入可视区,把0号GameObject位置放在滑动面板最后,如同所示

UGUI Scrollrect滚动优化:无限循环利用_第2张图片

 

 

 

同时更新滑动面板大小,和每个条目信息。这样循环下去一共创建5个gameobjec,重复利用,实现显示N个条目。如图所示

UGUI Scrollrect滚动优化:无限循环利用_第3张图片

 

 

 

只创建了5个GameObject,可以实现N个条目的显示。

2 详细设计

2.1 初始化滑动面板

void InitValue()
    {
        if (ConstraintCount <= 0)
            ConstraintCount = 1;
        Debug.Log("maxIndex = "+ maxIndex);
        if (minIndex > maxIndex) minIndex = maxIndex;
        mTrans = transform;
        mRTrans = transform.GetComponent();
        mScroll = transform.parent.GetComponent();
        mHorizontal = mScroll.horizontal;
        
        SR_size =transform.parent.GetComponent().rect.size;

        //四角坐标  横着数
        conners[0] = new Vector3(-SR_size.x / 2f, SR_size.y / 2f,0);
        conners[1] = new Vector3(SR_size.x / 2f, SR_size.y / 2f,0);
        conners[2] = new Vector3(-SR_size.x / 2f, -SR_size.y / 2f,0);
        conners[3] = new Vector3(SR_size.x / 2f, -SR_size.y / 2f,0);
        for (int i = 0; i < 4; i++)
        { 
            Vector3 temp = transform.parent.TransformPoint(conners[i]);//转化为世界坐标,4个顶点
            conners[i].x = temp.x;
            conners[i].y = temp.y;
        }

        mRTrans.pivot = new Vector2(0, 1);//设置panel的中心在左上角
        
        mScroll.onValueChanged.AddListener(delegate { WrapContent(); });//添加滚动事件回调
        startPos = mTrans.localPosition;
}

1.得到显示区域的4个顶点的世界坐标

2.当产生滚动时,添加滚动委托

2.2 重置滑动面板大小

void UpdateRectsize(Vector2 pos,bool isLast = true)
    {
        if (arrangeType == ArrangeType.Vertical)
        {
                mRTrans.sizeDelta = new Vector2(pos.x + cell_x/2, ConstraintCount * cell_y);
        }
        else
        {
                mRTrans.sizeDelta = new Vector2(ConstraintCount * cell_x, -pos.y + cell_y/2);
        }
}

当有新的条目加入时要重新设置滑动层的大小,相当于添加ContentSizeFitter组件。

2.3滑动更新

float min = conner_local[0].x - cell_x;//显示区域
            float max = conner_local[3].x + cell_x;
            for (int i = 0, imax = mChild.Count; i < imax; i++)
            {
                Transform temp = mChild[i];
                float distance = temp.localPosition.x - center.x;
                
                if (distance <-extents)
                {
                   
                    Vector2 pos = temp.localPosition;
                    pos.x += extents * 2f;

                    int realIndex = getRealIndex(pos);

                    if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))
                    {
                        if (i == imax -1)
                            UpdateRectsize(pos,true);
                        else
                            UpdateRectsize(pos);
                        temp.localPosition = pos;
                        //设置Item内容
                        UpdateItem(temp, i, realIndex);       
                    }
                    
                }

                if (distance > extents)
                {
                    Vector2 pos = temp.localPosition;
                    pos.x -= extents * 2f;

                    int realIndex = getRealIndex(pos);

                    if (minIndex == maxIndex || (realIndex >= minIndex && realIndex < maxIndex))
                    {      
                        temp.localPosition = pos;
                        //设置Item内容
                        UpdateItem(temp, i, realIndex);                
                    } 
                }

1.在滑动委托中,每次遍历所有的创建的GameObject(这里是5个)

2.当水平向左滑动时,当GameObject超过可视区的最左边,把它放在可视区的最右边的预备显示位置,如图所示,0号GameObject从最前变为最后。同时增加滑动面板大小,和0号GameObject的信息显示(把0置为5)

UGUI Scrollrect滚动优化:无限循环利用_第4张图片

 

3.当水平向右滑动时,当当GameObject超过可视区的最右边,把它放在可视区的最左边的预备显示位置,如图所示,0号GameObject从最前后为最前。0号GameObject的信息显示(把10置为5)。这样实现无限滚动。

UGUI Scrollrect滚动优化:无限循环利用_第5张图片

 

demo地址 

https://download.csdn.net/download/luoyikun/9556959

我设置的是1积分,但是下的人多了csdn会自己涨分

 

你可能感兴趣的:(Unity3D实用技术笔记,Unity3d技术笔记)