【分享】简单方便的UI渲染优化 - SortingGroup (支持原生,支持2.4.x,无需自定义引擎)

前言

相信大部分人都做过UI渲染优化,其重点也就是合批。但是在当前cocos使用节点树深度遍历的方式中,想要把相同类型的组件放在一起,势必会修改节点树,很可能破坏掉优雅合理的节点组织结构;还有可能因为节点树的改动,需要添加一些冗余糟糕的代码。
最近刚好有时间,逛论坛的时候看到有同学提这类问题,各位大哥也给出了解决方案,就是在渲染的时候给节点重新排序。于是心血来潮去看了下3.6.3的源码,好像要实现其实挺简单的。

原理

为需要排序的UI渲染器设置排序优先级; 在UI渲染遍历节点树阶段,不立即执行各种UI渲染器,而是把UI渲染器缓存起来;在UI渲染遍历完节点树后,对UI渲染器缓存通过排序优先级进行排序后执行。然而,遮罩会打断这一过程,所以如果项目中大量使用了遮罩,优化效果可能会不太明显。

效果对比

在ScrollView下生成200个项目测试对比。

测试设备:HUAWEI P30 Pro

项目预制体结构:
QQ截图20230205190757

项目越多,差距越明显。

使用方式

看到标题的时候,相信使用过Unity的同学就差不多知道使用方式了。API设计其实就是照搬的Unity的SortingGroup。使用步骤如下;

  1. 导入扩展包lcc-ui-sorting-group到项目assets目录内

  2. 如果是原生项目,需要进行以下步骤;

    • 3.6.x项目:

      • 检查Native扩展包lcc-ui-sorting-group-nativereadme.txt文件,以确保匹配creator版本

      • 构建原生项目,在根目录生成native目录

      • 导入Native扩展包lcc-ui-sorting-group-nativenative/engine目录下

      • 复制lcc-ui-sorting-group-native/backup/CMakeLists.txt文件到引擎Native目录替换。主要是引擎的CMakeLists.txt文件没有提供自定义接口。扩展包的CMakeLists.txt只是添加了部分自定义接口,在删除此插件的时候可以选择保留,不会有其他影响。

      • 修改native/engine/common/CMakeLists.txt文件,在代码include(${COCOS_X_PATH}/CMakeLists.txt)上面添加插件配置,具体如下;

        ...
        
        # 插件配置 引入lcc-ui-sorting-group native部分
        
        include(${CMAKE_CURRENT_LIST_DIR}/../lcc-ui-sorting-group-native/CMakeLists.txt)
        
        include(${COCOS_X_PATH}/CMakeLists.txt) #在这一行上面插入插件配置
        
        ...
        
    • 2.4.x项目:

      • 检查Native扩展包lcc-ui-sorting-group-nativereadme.txt文件,以确保匹配creator版本

      • 构建原生项目,需要选择模板为default, 会在根目录生成build/jsb-default目录

      • 复制Native扩展包lcc-ui-sorting-group-native/cocos2d-x下的所有文件到build/jsb-default/frameworks/cocos2d-x目录以覆盖引擎原始文件

  3. 定义排序层枚举,扩展包目录如下 QQ截图20230205173234 ,打开sorting-define.ts文件,添加或修改SortingLayer枚举。

/**
 * 排序层级
 */
export enum SortingLayer {
    
    //-- 自定义,在此之上,小于 DEFAULT 的层级

    /** 
     * 默认层级,在没有应用排序的UI渲染上的默认层级
     */
    DEFAULT = 0,

    //-- 自定义,在此之下,大于 DEFAULT 的层级

    // 测试定义,可以直接移除
    TEST_LIST_ITEM = 1,
}

/**
 * 在层级中最大排序值
 */
export const ORDER_IN_LAYER_MAX = 100000;
  1. 在需要排序的UI节点上,添加SortingGroup组件,并设置排序层和排序值,其配置会应用于当前节点和子孙节点上的UI渲染器; QQ截图20230205173334
    UI渲染器的优先级以当前节点或者最近的祖先节点上的SortingGroup组件配置为准,如果没有则默认为0
    和Unity不同的是Order In Layer不必是整数,这里可以使用小数。不同Sorting Layer的情况下,Sorting Layer枚举越小越先渲染;相同Sorting Layer的情况下,Order In Layer的值越小越先渲染。

示例工程

gitee开源项目 3.x & 2.4.x

注意

  1. 该扩展包对引擎进行过小改,如果想移除这个功能,在删除扩展包目录后需要重启编辑器。
54赞

顶一下明天再看看

原生跟你有仇嘛

优雅永不过时

:call_me_hand:

感谢大佬分享

大概原生的这部分是由c++实现

主要是想在不自定义引擎的情况下,对引擎进行修改,这样使用更简单

1赞

插眼。嘿嘿:drooling_face::drooling_face::drooling_face:

谢谢你的好功能。
我使用的是 2.4.11 版。
我该如何应用它?

因为2.4.x和3.x的UI系统完全不一样,我看了一下也可以做。但是原生由于没有使用3.x类似的CMake系统,好像只有自定义引擎一条路

1赞

mark一下

刚从平行光跟帖过来,6啊。马上搬到项目去。 :crazy_face:

mark UI渲染优化 :100:

mark 给你点赞

战术mark

牛逼89822D38AB234E4A2EC1836C3E79B89E 点个赞

一键三连,感谢分享!

这个官方是不是可以跟进下直接移植到引擎里

我也希望官方能提供这种功能
这个功能如果不使用,我简单的测试了一下,和原版相比基本没有什么性能损失
如果使用,优化就会方便很多,性能提升也较明显