CocosCreator 游戏开发 - 利用 AssetsBundle 技术对小游戏包体积进行优化

总所周知,小游戏因为是依附于别的应用软件平台,因为不是一个独立的应用,始终或多或少会收到原依附平台的限制,其中游戏包体积应该大部分的开发者都会遇到过。

其中例如图片、音乐等一些静态资源则可以使用服务器远程加载,但是更多的游戏配置数据和游戏逻辑代码则不能通过远程服务器进行动态加载。一方面为了将小游戏的包体积压缩至平台限定的大小,另一方面为了小游戏的首屏加载时间尽可能短首次加载的代码包体积也应该足够小。

在 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.getBundle api 传入分包 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;
});

这里给自己开发的一个微信小游戏做下引流,微信搜索 "坦克幸存者" 或者来扫下面的小游戏码多来玩玩小游戏来支持下这位可怜贫困的前端搬砖仔。

相关推荐
雪碧聊技术7 小时前
前端项目代码发生改变,如何重新部署到linux服务器?
前端·vue3·centos7·代码更新,重新部署
liulilittle8 小时前
C++ 浮点数封装。
linux·服务器·开发语言·前端·网络·数据库·c++
wordbaby8 小时前
Expo 进阶指南:赋予 TanStack Query “原生感知力” —— 深度解析 AppState 与 NetInfo
前端·react native
Moment8 小时前
从美团全栈化看 AI 冲击:前端转全栈,是自救还是必然 🤔🤔🤔
前端·后端·面试
天问一8 小时前
使用 Vue Router 进行路由定制和调用的示例
前端·javascript·vue.js
韩立学长10 小时前
【开题答辩实录分享】以《基于Vue的非遗文化知识分享平台的设计与实现》为例进行选题答辩实录分享
前端·javascript·vue.js
优弧10 小时前
离开舒适区100天,我后悔了吗?
前端·后端·面试
胡gh10 小时前
css的臂膀,前端动效的利器,还是布局的“隐形陷阱”?
前端·css·html
灵感菇_10 小时前
Flutter Riverpod 完整教程:从入门到实战
前端·flutter·ui·状态管理
用户214118326360210 小时前
紧急修复!Dify CVE-2025-55182 高危漏洞,手把手教你升级避坑
前端