cocosCreator 之 Bundle(二)

版本: v3.4.0

参考:Asset Bundle


简介

关于Bundle,可以理解为资源模块化,允许开发者按照项目需求将贴图,脚本等资源划分在多个不同的Bundle中。

在项目运行的过程中,根据需求去加载不同的Bundle,以减少启动时加载的资源数量等。

通过AssetManager下的BuiltinBundleName可以得知:

export namespace AssetManager {
    
    
  // 内置 bundle
  export enum BuiltinBundleName {
    
    
    RESOURCES = "resources",
    MAIN = "main",
    START_SCENE = "start-scene"
  }
}

引擎内置的Bundle,主要有:

  • main 存放所有在构建发布面板的参与构建场景中勾选的场景以及依赖资源,通过主包压缩类型配置主包为远程包而生成。
  • resources 通过配置资源管理器中的assets目录下生成resources文件夹,更多内容参考:cocosCreator 之 resources(一)
  • start-scene构建发布面板上勾选了初始场景分包,则首场景将会被构建到start-scene

内置的Bundle,在构建发布中设置以后,在打包构建的时候,就会生成。以mainresources为例:

请添加图片描述

构建以后,在build的android-001下目录下,会生成出来:

请添加图片描述

Bundle的目录结构都是类似的,主要内容:

  • 代码 代码相关会根据平台合并生成一个index.jsgame.js的入口脚本文件
  • 资源 资源及依赖资源会放到importnative目录下
  • 资源配置 资源的配置信息相关放在config.json

配置

Bundle除了官方内置以外,也支持自定义配置。它的配置是以文件夹为单位的,当我们在资源管理器选择某个文件夹时,属性检查器就会出现一个配置为Bundle的选项。

请添加图片描述

在勾选配置为Bundle的选项后
请添加图片描述

官方给予了很好的提示,其配置参数:

配置参数 说明
Bundle名称 构建名称,默认使用文件夹名字,可根据需要修改
Bundle优先级 构建时按照从大到小的顺序进行构建,优先级的设置可以相同,但要主要尽量保证共享的资源TextureSpriteFrameAudio等Bundle的优先级更高
目标平台 不同平台可使用不同的配置,构建时根据平台来生成Bundle
压缩类型 不同平台有着不同的压缩类型
配置为远程包 如果勾选,则构建后会放到remote文件夹中,该内容需要放到远程服务器上

针对于压缩类型,主要有如下几种:

压缩类型 说明
无压缩 没有任何压缩操作
合并依赖 构建Bundle时,将相互依赖资源的JSON文件合并到一起,减少运行时加载请求的次数
合并所有JSON 构建Bundle时,会将所有的JSON资源合并为一个,在web平台可以最大化减少请求数量,但会增加单个资源的加载时间。在Android平台不推荐使用,它会增加热更新的包体大小
小游戏分包 在提供了分包功能的小游戏平台,会将Bundle 设置为对应平台上的分包
ZIP 在部分小游戏平台,构建Bundle会将资源文件压缩成Zip文件,以减少运行时的加载请求数量

关于优先级相关,内置Bundle的层级个分别为:

Asset Bundle 优先级
main 7
resources 8
start-scene 20

注意: 自定义的Bundle优先级不要高于内置的Bundle,避免不能共享内置Bundle的资源。

另外,脚本也是支持Bundle的,如果设置Bundle后,则所有的脚本文件会合并为一个.js文件,在加载Bundle的时候,就会去加载这个js文件。

比如, 以assets/scripts为例,在设置Bundle后,通过android构建发布构建

请添加图片描述

其中的index.js文件就包含了所有的脚本文件内容相关。


脚本加载

脚本中使用Bundle,主要通过cc.assetManager,它的主要方法有:

export const assetManager: AssetManager;
export class AssetManager {
    
    
  // 获取已加载的bundle集合
  bundles: __private.cocos_core_asset_manager_cache_ICache<AssetManager.Bundle>;
  // 获取内置main包
  get main(): AssetManager.Bundle | null;
  // 获取内置resources包
  get resources(): AssetManager.Bundle | null;
  // 获取已加载的分包
  getBundle(name: string): AssetManager.Bundle | null;
  // 移除指定的bundle包
  removeBundle(bundle: AssetManager.Bundle): void;
  // 加载包
  loadBundle(name, options, onComplete);
}

简单实例:

// 加载script Bundle 
assetManager.loadBundle("DemoBundle", (err: Error, data) => {
    
    
  console.log("loadBundle data:", data);
});

// 获取已加载的bundle
let scriptBundle = assetManager.getBundle("DemoBundle");
console.log("已加载的scriptBundle:", scriptBundle);

注意:

  • 除内置的mainresources的Bundle外,其他自定义的Bundle必须在加载完成后,才能通过getBundle获取到
  • 针对脚本,最好不要互相引用,可能会导致运行时找不到脚本

针对于Bundle的使用,大概与resources的使用是类似的。 具体的方法有:

  • load 加载资源
  • loadDir 批量加载资源
  • preload 预加载资源
  • preloadDir 预加载目录中资源

更多内容可参考上篇博客cocosCreator 之 resources(一) ,简单的实例:

protected onLoad(): void {
    
    
  // 加载Bundle
  assetManager.loadBundle("DemoBundle", (err: Error, bundle) => {
    
    
    if (err) {
    
    
      return console.error(err);
    }
    this.initBundle(bundle);
  });
}

private initBundle(bundle: any) {
    
    
  console.log("bundle名字:", bundle.name);
  console.log("bundle的根路径:", bundle.base);
  console.log(bundle);

  // 预加载bundle资源
  bundle.preload("sound/click", (err, data) => {
    
    
    if (err) {
    
    
      return console.error(err);
    }
    console.log("localConfig data:", data);
  });

  // 预加载目录资源
  bundle.preloadDir("spine", (err, data) => {
    
    
    if (err) {
    
    
      return console.error(err);
    }
  })

  // 加载资源
  bundle.load("sound/click", (err, data) => {
    
    
    if (err) {
    
    
      return console.error(err);
    }
    console.log(data);
  });
}

猜你喜欢

转载自blog.csdn.net/qq_24726043/article/details/132137715