V7投稿 | 手把手教你搭框架——资源管理(秒Loading、大厅子游戏、同步加载、极简对象池、多语言)

image
对CocosCreator3.x资源管理模块进行封装,优化现有功能,添加新功能

一、做哪些优化
image
二、如何获取

1、https://gitee.com/szrpf/AssetManager3.x

2、解压,导入cocos creator(版本3.8.2),可以运行演示Demo

3、API文档:https://www.showdoc.com.cn/2489869925397932/11076318197826428

三、功能演示

为了演示框架功能,按以下步骤操作:

打开演示Demo 和 API文档
image
1、设置当前场景为:Loading,并打开同名的ts脚本
image
这里演示了如何制作Loading页面

通过gi.loadBundle加载主包所有资源到缓存

每加载一个资源,会触发一次回调,传出3个参数:

progress:当前加载进度(取值范围0~1,用于更新进度条)
path:当前加载的资源路径(用于识别当前加载的是哪个资源)
asset:当前加载的资源(用于给对应的组件赋值,显示组件内容)

点运行,可以看到进度条变更,加载完毕后跳转到游戏场景。

2、打开Game.ts脚本
image
这里演示了进入游戏后如何加载分包
image
首先将编辑器里,用到分包资源的地方统统置空,例如:

Sprite就把SpriteFrame置空
Spine就把SkeletonData置空
音频就把AudioClip置空

这样引擎就不会自动加载分包里的资源,保证Loading速度

进入游戏后,调用gi.loadBundle开始加载分包

用path判断当前加载了哪个资源,并将asset赋值给所在的组件

这样每加载一个分包资源,就会立即在游戏中更新出来

想要Loading更快,就把更多主包资源放到分包,但要保证核心玩法不受影响

3、找到“演示如何同步换图换Spine”
image
这里演示了用 gi.load 同步换图、换Spine

4、找到“演示如何调用其他子游戏的资源”
image
这里演示了在没有缓存的情况下,异步加载其他子游戏的资源

只要是Bundle包内的资源,无论是否已缓存,都可以用 gi.loadAsync 异步加载
如果已缓存,gi.loadAsync直接从缓存中读取
如果未缓存,gi.loadAsync异步加载到缓存再读取
注意:

  • 所有资源加载函数,都只操作当前子游戏的缓存
    调用gi.setChannel可以切换子游戏

  • 调用异步函数需要加async / await关键字
    确保异步函数能像同步函数一样,从上往下逐行执行

5、资源加载的进阶封装
image
基于gi.load,封装了通过资源路径,同步创建节点的gi.create
image
功能类似于:从“资源管理器”中直接拖资源到“层级管理器”

基于gi.create,封装了从对象池获取节点的gi.poolGet(参数和create一样)
以及把节点放回对象池的gi.poolPut

同样基于gi.loadAsync,封装了异步创建节点的gi.createAsync
基于gi.createAsync,封装了异步从对象池取节点的gi.poolGetAsync

调用方式较简单,考虑篇幅不做演示。
注意:以上接口创建的节点Layer都是默认的DEFAULT
如果节点渲染不出来,请检查Camera的Visibility是否包含DEFAULT

6、设置当前场景为:多语言演示,并打开同名ts脚本
image
这里演示了如何切换多语言

Step 1:配置每个语种的参数表,包括文字内容、图片路径
image
"XXL/MainPack/LangZH.json"和"XXL/MainPack/LangEN.json"分别是中英文的参数表

Step 2:gi.langLoad初始化语种参数表

Step 3:gi.setChannel设置语种,注意第2个参数要填ChannelOf.language
image

四、小Tips

1、如何在自己的项目中使用这套资源管理框架

复制Demo中的gi.ts到自己项目的assets目录下
复制Demo中的gi.d.ts到自己项目的根目录下(与assets目录同级)
任何脚本中,通过gi就可以访问框架API,类似2.x的cc

2、关于图片类型
image
单张图片要设置成sprite-frame类型
Spine的图片要设置成texture类型

3、建议复制Demo中的".vscode" 和 ".gitignore"到自己项目中
image
.vscode中的2个文件:
launch.json vscode中按F5可以断点调试
settings.json vscode中过滤无意义的文件
.gitignore 中做了配置,确保.vscode目录能上传git

4、bundle包名称要重命名成“channel+bundleName”
例如:子游戏’Fish’的’MainPack’,要重命名成’FishMainPack’
image
重命名的方法是,资源管理器里选中bundle,属性面板里修改Bundle名称
bundle重命名,只有大厅子游戏才需要,单游戏项目不需要
单游戏项目也完全不需要调用gi.setChannel切换子游戏

五、结束语
image
技术基本功决定下限
设计架构能力决定上限
不想面临35岁裁员危机
就多多锻炼框架设计能力吧
加油:sunglasses::sunglasses::sunglasses::sunglasses::sunglasses::sunglasses::sunglasses:

Gitee地址:https://gitee.com/szrpf

EMail地址:27185709@qq.com

推荐链接:

1、【包教包会】CocosCreator Assembler经典案例第二期——圆角矩形(支持原生、可合批、附Demo源码)

2、【包教包会】CocosCreator Assembler经典案例第一期——2D实现3D透视翻转(附Demo源码)

3、【包教包会】对CocosCreator富文本RichText进行全面优化

4、【包教包会】对CocosCreator拖尾组件MotionStreak做了全面优化

5、【包教包会】重写CocosCreator的按钮Button组件,动画、音效、回调逻辑优化

mi

8赞

太卷了 :clap: :clap: :clap:

有个疑问, 每个bundle都把所有的资源全部加载到内存吗?
会不会出现内存居高不下?

肯定会,这个感觉就临时写一写,没有资源回收

1赞

只有真正调用boundle.load才会真正加载资源,不过社区框架太多了其实都大同小异

给大佬点赞!
投稿记得在活动贴评论区贴链接哟!

Demo主要是演示功能
要释放资源可以选择以下2个接口:
gi.releaseBundle释放Bundle所有资源
gi.releaseAsset释放指定资源,参数缺省则释放当前子游戏全部资源

我认为这个设计并不好,跟函数名所表达的不一致,我觉得显示的加个参数来控制“如果缓存中有就同步读取”比较好

好哒,活动帖链接已贴:lollipop::lollipop::lollipop:

如果要同步加载,就用gi.load
如果要异步加载,就用gi.loadAsync
其实设计的初衷就是这样
至于gi.loadAsync发现该资源缓存里有,就直接读缓存,这只是个优化

大佬超神了

演示Demo有个Bug,已修复。
可以去gitee下载最新版 :kissing_heart:

因为涉及微任务和宏任务执行时机的问题,某些特殊情况可能会出现问题,但也有可能几乎遇不到吧

:+1: :+1: :+1:

:+1: :+1: :+1: :+1: :+1:

留个眼,刚好有需要