[讨论]基于AssetBundle的大厅子游戏实现思路

[讨论]基于AssetBundle的大厅子游戏实现思路

2.4.0 发布了 assetbundle 功能,

###通过分析官方实现的功能,发现:

  1. 如果bundle 为远程包, 第一次加载时必须下载才能使用
  2. 如果bundle 为非远程包, 虽然无需下载,但是只能用传统的热更新方式进行更新

###希望实现

  • bundle可内置,也可以远程.
  • 发布新包时,希望旧版本也能同步更新bundle.
  • 不管内置还是远程包都可以进行更新.

###如何将远程包放入到apk内加载?
这里要分两种情况.注意,构建打包时都勾选md5cache.版本号指构建后的bundle version

1. bundle在同一个工程内.

* 设置bundle为远程包,记录版本号V1.
* 设置bundle为非远程包.打入apk1 (iOS也一样适用)内. 此时apk1 内本地版本为V1
* 生成远程包V2.
* apk1运行时,通过服务端下发判断需要更新V2,则加载远程包V2. 
* 更新apk2时将V2版本号写入,加载本地版本V2.

加载方式
* 加载apk内的bundle  `loadbundle(bundleName,{version:V1},(err,bundle)=>{...})`
* 加载远程的bundle  `loadbundle('http://yourdomain/'+bundleName),{version:V2},(err,bundle)=>{...})`

弊端
* 需要两次打包.
* 第一次加载远程包时为完整下载. 
* 对于加载本地和远程版本是两个不同的方法


如果不想打包两次
* 需要修改main.js ,在cc.assetManager.init ,去掉需要本地加载的bundle数组.
* 构建完毕拷贝需要本地加载的bundle 到 build/assets/目录下
cc.assetManager.init({ 
        bundleVers: settings.bundleVers,
        //remoteBundles: settings.remoteBundles,
        remoteBundles: [],//所有远程包都去掉了.
        server: settings.server
    });

2. bundle在另外的项目

  • 拷贝外部bundle到 build/assets/ 目录
  • 修改 main.js 添加外部bundle 到 bundleVers.
    cc.assetManager.init({ 
        bundleVers: Object.assign(settings.bundleVers,{bundleA:"bundleAVer",bundleB:"bundleBVer}),
        remoteBundles: settings.remoteBundles,
        server: settings.server
    });

期望的效果

上面的方法的一大弊端就是 第一次更新远程包时需要完整下载 无法增量更新.
最好的效果是可以将bundle 放入到apk内,并且也可以跟其他远程包一样进行增量更新.

分析远程包下载目录 data/data/packname/files/gamecaches
cacheList.json 该文件记录了远程bundle所需的文件下载缓存列表.它通过cc.assetManager.cacheManager 进行缓存管理和文件的写入

* 在第一次启动时,将apk内的bundle zip 解压到gamechaches目录;
* 将bundle内文件添加进入cacheList缓存.

这样操作后, 直接使用 加载远程的bundle 的方法 进行加载即可.

优点:
* 可控的包体减小(zip压缩).
* 核心体验无需下载
* 修改文件较多时, 可实现远程整包zip下载.

缺点

  • 首次启动需要解压,如果文件较多,需要比较长的等待时间.
1赞

我现在是用2.4版本,将一个游戏相关的资源放在一个bundle目录下,但这样一个游戏改动了,打包就会全打一遍,游戏多的话,肯定会慢很多,有没有办法只打包指定的bundle文件夹

有demo吗?

有没有demo参考一下

跟我的思路一样,目前卡在 load 本地bundle 接着load 远程bundle后 preload 远程文件没反应的问题上。

  1. cc.assetmananger.loadbundle({local_path}, {version:xxx} …)

  2. cc.assetmanager.loadbundle{remote_path},{version:yyy} …)

  3. bundle_from_2.preloaddir(’/’) … 这一步居然不会下载变动的更新文件。

在步骤3之前执行 bundle_from_1.releaseAll() ; cc.assetmanage.removebundle(bundle_from_1) 也不行

大佬们,请教一下,我也是通过zip下载的,然后cacheList.json应该怎么去更新呢

提供一个单独打包的实现思路,将bundle包单独拷贝出来,公共资源拷贝出来,新建一个项目,然后在打包这个项目,最后打包出来就只剩主包和拷贝出来的bundle包,最后再将这个bundle包做处理就行了

分析远程包下载目录 data/data/packname/files/gamecaches
cacheList.json 该文件记录了远程bundle所需的文件下载缓存列表.它通过 cc.assetManager.cacheManager 进行缓存管理和文件的写入

* 在第一次启动时,将apk内的bundle zip 解压到gamechaches目录;
* 将bundle内文件添加进入cacheList缓存.

先下载非zip的远程包. 然后打开 cache.plist 文件. 记录内容.
下载zip远程包解压放到跟 非zip远程包一个路径, 还有就是写cache.plist.

好的,谢谢你的指导,已经明了了

大佬,再请教你一下,我这里zip成功下载解压后,里面的remote资源也写入到cacheList.json文件了,但是还是不行,然后我再重启游戏,还是不行,是还需要什么操作吗?是不是版本的问题?我用的v 2.4.6


一直报错,这个路径找不到,但是路径下面确实是有东西的,cacheList.json文件也是没问题的

1 . cacheList.json 有你需要下载的文件吗? (例如加载bundle,第一个文件就是 config.json )
2. 检查loadBundle 是不是没有加版本号? 例如打包 fgui/config.abcd.json 那么加载时需要 loadBundle(fgui,{version:abcd})

多谢多谢,周六的时候已经解决了,是我自己的一个小失误