UIGrid/UITable 性能优化

本文为作者原创,转载请注明出处:https://www.cnblogs.com/zhaoqingqing/p/4919980.html



性能优化#

排行榜,邮件,关卡等数据列表项,一般在玩家打开面板时,都会重新刷新一次数据,那是否有必要每次都生成列表项呢?

假如每次列表的内容有变动就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)
    {
        
    }
}
复制代码
作者:赵青青   一名在【网易游戏】做游戏开发的程序员,擅长Unity3D,游戏开发,.NET等领域。
本文版权归作者和博客园共有,欢迎转载,转载之后请务必在文章明显位置标出原文链接和作者,谢谢。
如果本文对您有帮助,请点击【推荐】您的赞赏将鼓励我继续创作!想跟我一起进步么?那就【关注】我吧。
posted @   赵青青  阅读(1829)  评论(3编辑  收藏  举报
编辑推荐:
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
阅读排行:
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示
CONTENTS