--- sidebar_position: 1 description: "详细了解该缓存模式重构后的所有新特性。" --- # Char 缓存模式 在 [提升游戏性能](../../best-practices/performance-guide) 中,我们提到了社区版使 Bitmap 与 Char 缓存模式都支持了废弃字符空间复用的特性。 除此之外,Char 缓存模式还提供了一些可调整的设置。 ## 在场景切换时清空所有字符图集 控制在场景切换时是否会清空所有的字符图集,考虑到旧项目兼容,默认为开启状态。 ```js cc.sp.charAtlasAutoResetBeforeSceneLoad = false; ``` 在引擎原来的设计中,该机制不可被关闭,现在推荐关闭该机制。 ## 字符图集的数量与内置材质 现在在内部最多会创建 8 张字符图集,与多纹理材质的最大纹理插槽数一致,如果合理使用缓存模式,8 张应该对所有项目都是足够的。 Char 缓存模式会在内部维护一个使用内置多纹理 Effect 着色器的材质,Label 在渲染时会先判断当前所使用的是否为多纹理材质,是的话则判断是否能在材质纹理插槽中找到字符图集纹理。 若任何判断不满足则会将组件的材质设为内部维护的材质。 如果你有特殊的用途,可以通过以下代码获取: ```js cc.Label._shareAtlas.material; ``` 需注意 Char 字符图集是运行时才创建的,所以现在**暂时无法在 Char 缓存模式下设置组件的自定义材质**。 要解决这个问题,你可以通过代码创建含有当前所有字符图集纹理的自定义材质来解决这个问题,但内部会不断创建新的字符图集(直到 8 张),所以需注意同步更新这个自定义材质,建议有自定义材质需求时使用 Bitmap 缓存模式。 ## 与动态图集合批的注意事项 多纹理材质只有 8 个纹理插槽,默认情况下字符图集自动多纹理合批的数量为 1,也就是说会将第 1 张字符图集纹理放入材质。 **你可以自己调整这个分配值,但请注意调整的时机。** 下面举一个例子,假设有一个脚本 `example.ts` 的部分内容是: ```js class Example extends cc.Component { onLoad() { // 1 } } // 2 ``` 一般情况下,代码位置 2 是当用户脚本被加载时就会被执行,而代码位置 1 可能需要等到引擎首场景加载后的某个时间执行。 社区版会自动调整动态图集的最大数量,这个调整的时机是在代码位置 2 之后的,所以比如你的项目对 Char 缓存模式使用量比较大时,想尝试将动态图集最大数量调整为 6,自动合批的字符图集数量调整为 2,那么你只需要在代码位置 2 修改字符图集自动多纹理合批的数量: ```js cc.sp.charAtlasAutoBatchCount = 2; ``` 之后社区版会自动将动态图集的最大数量调整为 `8 - 2`,即 6。 这个自动调整的时机并不意味着你在代码位置 2 修改动态图集的最大数量是无效的,因为一开始动态图集的最大数量为 `-1`,你打印一下可以看到 ```js console.log(cc.dynamicAtlasManager.maxAtlasCount); // -1 ``` 如果你在代码位置 2 修改了动态图集的最大数量,社区版就不会调整该值了。 ```js cc.dynamicAtlasManager.maxAtlasCount = 5; ``` 这时候动态图集的最大数量是 5,字符图集自动多纹理合批的数量依旧默认为 1,多纹理材质会有 2 个空纹理插槽。 如果这两个数量加起来超过 8 就会使用更多的材质进行渲染,这会导致项目的 Draw Call 数量升高,建议保持加起来的数量不超过 8 张,能保持 1 Draw Call。 ```js cc.dynamicAtlasManager.maxAtlasCount = 13; cc.sp.charAtlasAutoBatchCount = 3; ``` 比如上面这个设置,这会使得引擎需要用 2 个材质进行渲染,但是可用的动态图集扩充到了 13 张,Char 能自动合批的图集数量扩充到了 3 张,对于某些项目来说可能并不是一件坏事。 社区版使用这个 “7 + 1” 的默认值有以下几点原因: - 引擎原本就只有 1 张 Char 字符图集 - 大多数项目使用 1 张 Char 字符图集是足够的