总所周知,小游戏因为是依附于别的应用软件平台,因为不是一个独立的应用,始终或多或少会收到原依附平台的限制,其中游戏包体积应该大部分的开发者都会遇到过。
其中例如图片、音乐等一些静态资源则可以使用服务器远程加载,但是更多的游戏配置数据和游戏逻辑代码则不能通过远程服务器进行动态加载。一方面为了将小游戏的包体积压缩至平台限定的大小,另一方面为了小游戏的首屏加载时间尽可能短首次加载的代码包体积也应该足够小。
在 Cocos Creator 当中肯定也提供了这方面应对处理的方式,那就是 AssetsBundle 这个小游戏分包技术。
Asset Bundle 介绍 | Cocos Creator
- 因为 AssetsBundle 写起来文字太多了,后续 AB 包这个简称就是代指 AssestBundle 包。
和小程序分包类似,不过这个是针对小游戏的分包操作。
顺带这里贴个很久之前工作上关于小程序分包优化的历程记录文章:juejin.cn/post/713991...
Cocos Creator 当中想要设置小游戏分包处理和小程序的有不同的操作处理。
设置分包目录
首先需要在 CocosCreator 引擎编辑器当中设置目录作为分包目录:
如图所示,在这里这个 Bundle 勾选项是设置该目录是否需要作为分包进行处理:

勾选了 Bundle 勾选项,后会有相关的一些分包配置:
- Bundle 分包标识,后续会有相关逻辑需要根据这个标识进行查找这个 Bundle 分包的逻辑;
- Bundle 分包加载优先级;

拉取 AB 分包资源
设置分包配置目录后,在小游戏运行当中针对 AB 包是并不能直接进行调用使用的,需要先进行拉取加载分包资源先。
- 这里需要引入 CocosCreator 引擎的
assetManager依赖调用assetManager.loadBundle方法传入前面设置分包包名来进行对应 Bundle 包的加载。
javascript
import { assetManager } from 'cc';
assetManager.loadBundle('common', (err, bundle) => {
// 跟 Node.js 的异步处理方法类似,回调当中 err 参数没信息则证明加载分包成功了
if (!err) {
console.warn(bundle)
}
});
- 加载成功之后分包 Bundle 除了在回调当中能访问到 Bundle 对象外,还能通过
assetManager.getBundleapi 传入分包 Bundle 名字,来进行读取已加载缓存的分包 Bundle 对象。
ini
const commonModuleBundle = assetManager.getBundle('common');
因此我们能够将加载分包和获取 Bundle 的逻辑封装起来一个异步 Promise 方法,方便调用拉取分包获取 Bundle 处理:
typescript
// /utils/LoadUtils.ts
import { assetManager, AssetManager } from 'cc';
export const getAssetBundle = (bundleKey: string): Promise<AssetManager.Bundle> => {
return new Promise((resolve, reject) => {
if (assetManager.getBundle(bundleKey)) return resolve(assetManager.getBundle(bundleKey));
return assetManager.loadBundle(bundleKey, (err, bundle) => {
if (!err) return resolve(bundle);
return reject(err);
});
});
}
读取加载分包的内容
在分包资源拉取后,这时候才是和正常 CocosCreator 的 Resources 加载内容操作类似,只不过这时候就要用前面加载完成的分包 Bundle 对象调用相关加载内容的 api。
- 相关的加载/预加载/批量加载目录内容的 api 形式也是和 resources 动态加载类似,这里就简单贴几个 eg,具体可以参考对应的 resources 动态加载内容的官方文档:docs.cocos.com/creator/3.8...
javascript
// 加载 Prefab
bundle.load(`prefab`, Prefab, function (err, prefab) {
let newNode = instantiate(prefab);
director.getScene().addChild(newNode);
});
// 加载 Texture
bundle.load(`image/texture`, Texture2D, function (err, texture) {
console.log(texture)
});
// 加载 textures 目录下的所有资源
bundle.loadDir("textures", function (err, assets) {
// ...
});
// 加载 textures 目录下的所有 Texture 资源
bundle.loadDir("textures", Texture2D, function (err, assets) {
// ...
});
// 预加载
bundle.preload('images/background/spriteFrame', SpriteFrame);
bundle.load('images/background/spriteFrame', SpriteFrame, function (err, spriteFrame) {
spriteFrame.addRef();
self.getComponent(Sprite).spriteFrame = spriteFrame;
});
这里给自己开发的一个微信小游戏做下引流,微信搜索 "坦克幸存者" 或者来扫下面的小游戏码多来玩玩小游戏来支持下这位可怜贫困的前端搬砖仔。

