天天看点

UGUI ScrollRect 优化

UGUI Scroll Rect 加载大量Item 优化

开发环境:win7 64位 Unity 5.1 

和NGUI 一样  UGUI后期优化都要自己去实现。

Scroll Rect(Scroll View) 大量加载Item时,卡顿严重,接下来让我们简单粗暴的优化吧。

1.分析原因-为啥大量加载会卡顿?

NGUI中UIPanel裁剪 和UGUI中的Mask 遮罩一样,组件在视界外虽然不显示但还是参与了渲染工作。

有渲染就要消耗 Batches(Draw Call) 这样的设定吾辈无法接受。

UGUI ScrollRect 优化

2.解决问题。

获取scrollrect视界大小 和item大小,再计算出我们需要对象渲染的范围,超出这个范围我们就让它停止渲染(不是mask的遮罩)。

UGUI ScrollRect 优化

3.代码实现优化 

UGUI ScrollRect 优化

Item结构

UGUI ScrollRect 优化
<span style="font-size:14px;">public class AchieveManage : MonoBehaviour
{
    public ScrollRect scroRect;             //ScrollRect
    public VerticalLayoutGroup group;       //VerticalLayoutGroup
    public GameObject prefab_item;          //预设
    public int maxCount = 200;              //生产 数量  

    List<GameObject> list;                  
    float scroRect_MinHight;                 //预设高度
    float scroRect_MaxHight;                 //scrollrect 视图高度

    void Start()
    {
        //1.计算出 scrollrect 视图范围
        scroRect_MinHight = prefab_item.GetComponent<LayoutElement>().preferredHeight;  //获取预设高度
        scroRect_MaxHight = scroRect.transform.position.y + scroRect_MinHight;          //获取scrollrect 视图高度  

        list = new List<GameObject>();
        CreateAchieve();                    //创建成就
        StartCoroutine(IEShowInit());       //隐藏初始化
    }

    //创建成就
    void CreateAchieve()
    {
        for (int i = 0; i < maxCount; i++)
        {
            var go = Instantiate(prefab_item) as GameObject;
            go.SetActive(true);
            go.transform.position = Vector3.zero;
            go.transform.SetParent(group.transform);
            go.name = "item" + i;
            go.transform.FindChild("msg/txt1").GetComponent<Text>().text = go.name;
            list.Add(go);
        }

        
    }

    //2.拖动完毕委托事件 
    public void VCValueChanged()
    {
        list.ForEach((p) =>{CheckPos(p.transform);});
    }
    //3.检测 在scrollrect 视图内
    void CheckPos(Transform obj)
    {
        var pos = obj.position;
        var go = obj.gameObject;
        if (pos.y >= -scroRect_MinHight && pos.y <=scroRect_MaxHight)
            ShowItem(go);
        else
            HideItem(go);
    }
    //4.隐藏或显示
    void ShowItem(GameObject go)
    {
        go.transform.GetComponent<Image>().enabled = true;
        go.transform.FindChild("sprite").gameObject.SetActive(true);
        go.transform.FindChild("msg").gameObject.SetActive(true);
        go.transform.FindChild("but").gameObject.SetActive(true);
    }
    void HideItem(GameObject go)
    {
        go.transform.GetComponent<Image>().enabled = false;
        go.transform.FindChild("sprite").gameObject.SetActive(false);
        go.transform.FindChild("msg").gameObject.SetActive(false);
        go.transform.FindChild("but").gameObject.SetActive(false);
    }

    IEnumerator IEShowInit()
    {
        yield return new WaitForSeconds(0.3f);
        VCValueChanged();
    }
}</span>
           

4.调用测试,生成200Item batch 只有 60 ,如果没有优化瞬间飙到1K多....

UGUI ScrollRect 优化

NGUI 的scroll view优化也是这思路。

高能:此方法分分钟更改成动态加载。

继续阅读