NGUI UIScrollView UIGrid优化最佳方案,没有之一

来源:互联网 发布:蓄水池抽样算法 编辑:程序博客网 时间:2024/06/05 17:53

       对于UIScrollView存在大量item的时候,性能不佳一直被人诟病。然后很多人也弄了不错的方案,但感觉都不够美观,我觉得这个东西其实没有那么复杂。找了下原因,也很简单,因为NGUI在更新组件的时候,并不会判断是否可见,也就是说只要你scroll滑动了,那么所有的item都会重新draw一次。那当然会卡了。

       既然原因这么明显,那么直接将不可见的设置为active为false不就行了。

       测试了一下,果然没问题,最关键的隐藏不可见组件的代码:

       public void WrapContent ()
    {
        if(allChildren == null)
        {
            Debug.Log("no allchildren set");
            return;
        }
        if (!mInitDone) Init();
        if(scrollView == null)
        {
            return;
        }
        float itemSize = 0f;
        if(scrollView.canMoveHorizontally)
        {
            itemSize = cellWidth;
        }
        else
        {
            itemSize = cellHeight;
        }
        Vector3[] corners = mPanel.worldCorners;
        
        for (int i = 0; i < 4; ++i)
        {
            Vector3 v = corners[i];
            v = transform.InverseTransformPoint(v);
            corners[i] = v;
        }
        Vector3 center = Vector3.Lerp(corners[0], corners[2], 0.5f);
        if (scrollView.canMoveHorizontally)
        {
            float min = corners[0].x - itemSize;
            float max = corners[2].x + itemSize;
            
            for (int i = 0; i < allChildren.size; ++i)
            {
                Transform t = allChildren[i];
                if(t == null)
                {
                    continue;
                }
                //float distance = t.localPosition.x - center.x;
                float distance = t.localPosition.x;
                if (cullContent)
                {
                    //distance += mPanel.clipOffset.x - transform.localPosition.x;
                    if (!UICamera.IsPressed(t.gameObject))
                        NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false);
                }
            }
        }
        else
        {
            float min = corners[0].y - itemSize;
            float max = corners[2].y + itemSize;
            
            for (int i = 0; i < allChildren.size; ++i)
            {
                Transform t = allChildren[i];
                if(t == null)
                {
                    continue;
                }
                //float distance = t.localPosition.y - center.y;
                float distance = t.localPosition.y;
                if (cullContent)
                {
                    //distance += mPanel.clipOffset.y - transform.localPosition.y;
                    if (!UICamera.IsPressed(t.gameObject))
                        NGUITools.SetActive(t.gameObject, (distance > min && distance < max), false);
                }
            }
        }
    }

也很简单,直接放在UIGrid中,然后我自己给他添加了move事件,move 的时候就会调用这个函数,然后不断设置可见性,那么就可以保证永远只有屏幕中间的几个东西会被更新,放到手机上,果然非常滑溜。

0 0
原创粉丝点击