UIGrid/UITable 性能優化


性能優化

排行榜,郵件,關卡等數據列表項,一般在玩家打開面板時,都會重新刷新一次數據,那是否有必要每次都生成列表項呢?

假如每次列表的內容有變動就Instance 新的Gameobject,這是沒有必要的浪費。本文想做的就是避免頻繁生成新的Gameobject。

運行效果

grid_instance

思路及流程圖

循環利用UIGrid下已有child,改變child的數據(不同child渲染不同的數據)。需要生成時就生成,不需要生成則根據情況顯示隱藏

流程圖如下所示

image

實現方法

1、創建工具類:動態生成child ,隱藏多余的child

2、工具類使用方法:

                    傳入template obj(prefab)、data ,ResizeGrid

                    設置每一個Child的內容

XUIHelper

public  class XUIHelper
{
    /// <summary>
    /// 傳入指定數量, 對UIGrid里指定數量項SetActive(true)/或創建, 其余的SetActive(false)
    /// 常用於UIGrid下的對象動態增長
    /// </summary>
    public static void ResizeUIGridGameObjects(UIGrid uiGrid, int resizeCount, GameObject templateForNew = null)
    {
        if (templateForNew == null && uiGrid.transform.childCount <= 0)
        {
            CDebug.LogError("template為空  &&  uigrid childCount為0");
            return;
        }
        if (templateForNew == null) templateForNew = uiGrid.transform.GetChild(0).gameObject;
        _ResizeUIWidgetContainerGameObjects(uiGrid.transform, resizeCount, templateForNew);
        uiGrid.Reposition();
    }

    public static void ResizeUITableGameObjects(UITable uiTable, int resizeCount, GameObject templateForNew = null)
    {
        if (templateForNew == null && uiTable.transform.childCount <= 0)
        {
            CDebug.LogError("template為空  &&  uigrid childCount為0");
            return;
        }
        if (templateForNew == null) templateForNew = uiTable.transform.GetChild(0).gameObject;
        _ResizeUIWidgetContainerGameObjects(uiTable.transform, resizeCount, templateForNew);
        uiTable.Reposition();
    }

    public static void _ResizeUIWidgetContainerGameObjects(Transform transf, int resizeCount, GameObject templateForNew)
    {
        if (templateForNew == null)
            templateForNew = default(GameObject);

        for (int i = 0; i < resizeCount; i++)
        {
            GameObject newTemplate = null;
            if (i >= transf.childCount)  //child不足 instantiate
            {
                newTemplate = Object.Instantiate(templateForNew) as GameObject;
                newTemplate.transform.parent = transf;
                ResetLocalTransform(newTemplate.transform);
            }
            newTemplate = transf.GetChild(i).gameObject;
            if (!newTemplate.activeSelf)
                newTemplate.SetActive(true);
        }

        //多余的child setActive(false)
        for (int i = resizeCount; i < transf.childCount; ++i)
        {
            GameObject newTemplate = transf.GetChild(i).gameObject;
            if (newTemplate.activeSelf)
                newTemplate.SetActive(false);
        }
    }

    /// <summary>
    /// 模仿 NGUISelectionTool的同名方法,將位置旋轉縮放清零
    /// </summary>
    /// <param name="t"></param>
    public static void ResetLocalTransform(Transform t)
    {
        t.localPosition = Vector3.zero;
        t.localRotation = Quaternion.identity;
        t.localScale = Vector3.one;
    }
}

使用方法

public class XUILevel :CUIController
{
    private UIGrid LevelGrid;
    private List<CLevelInfo> LevelList;
    private GameObject LevelTemplate;

    public void RefreshUI()
    {
        //刷新Grid
        XUIHelper.ResizeUIGridGameObjects(LevelGrid, LevelList.Count, LevelTemplate);

        var idx = 0;
        foreach (var levelInfo in LevelList)
        {
            var child = LevelGrid.transform.GetChild(idx);
            child.name = "Level-"+levelInfo.Id;
            GetControl<UILabel>("Label", child).text = levelInfo.Name;
            child.GetComponent<UIEventListener>().onClick = OnClickLevel;

            //...... 其它的操作
            idx++;
        }
        LevelGrid.GetComponent<UIGrid>().enabled = true;
        LevelGrid.Reposition();
    }

    void OnClickLevel(GameObject obj)
    {
        
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM