微信小游戏资源热更新

关于微信小游戏资源热更新的讨论在论坛中已经有很多热门的帖子:

我这里提供一个新的思路,原理上上述2篇帖子已经说的很清楚了。我只是修改的方法有所不同。

我们都知道微信小游戏资源无法热更新,是因为加载bundle的json文件时候的后缀是settings.json中记录的,该文件会随主包一起发布到微信平台,无法做到随时热更新。
我们来先看看Cocos Creator导出微信工程的结构

  • 微信中js文件是不允许热更新的,只能上传到微信服务器
  • 我们希望做到的资源热更新是:仅仅prefab更改了,或者更换了一些资源能够热更新,紧急解决一些问题
  • Cocos打包仅仅资源更新的时候,随bundle附带的js文件也会更新,虽然内容不变但文件名中hash值部分会改变
  • 微信是不能更新js文件的,如何做到仅仅更新资源不改变原始bundle的js文件的加载呢?

通过前面帖子的启发,我找到微信小游戏平台加载bundle的关键代码,位置在引擎的:

  • engine\bin\adpater\minigame\wechat\engine-adapter.js

关键代码如下:

function downloadBundle(nameOrUrl, options, onComplete) {
  var bundleName = cc.path.basename(nameOrUrl);
  var version = options.version || cc.assetManager.downloader.bundleVers[bundleName];
  var suffix = version ? "".concat(version, ".") : '';

  ....

  var _config = "".concat(url, "/config.").concat(suffix, "json");
  downloadJson(_config, options, function (err, data) 

我的修改思路就是修改这段代码,修改为:

function downloadBundle(nameOrUrl, options, onComplete) {
  var bundleName = cc.path.basename(nameOrUrl);
  var newVersion = options.version || cc.assetManager.downloader.bundleVers[bundleName];
  var version = cc.assetManager.downloader.bundleVers[bundleName];
  var suffix = version ? "".concat(version, ".") : '';
  var newSuffix = newVersion ? "".concat(newVersion, ".") : '';

  ....


  var _config = "".concat(url, "/config.").concat(newSuffix, "json");
  downloadJson(_config, options, function (err, data) 

修改完之后使用命令压缩这个js,替换掉导出目录的engine-adapter.js,并且避免下次导出覆盖掉这个文件

这样修改原理如下:

  • 业务代码中加载bundle的时候指定version. 这个version可以是游戏启动时候先远程加载最新的资源bundle hash值信息,然后加载bundle时候指定这个version信息。这个version信息就是当前版本的最新资源bundle hash值
  • 加载代码时候仅仅加载bundle的json使用最新的指定的version信息,达到热更新资源的目的

我们目前项目采用的是这个修改方案:

  • 该修改方案修改简单,无需改动引擎,仅仅保留修改导出目录的engine-adapter.js
  • 加载资源最新的version方案大家可以自由发挥,这一步可以根据项目需要比较灵活

欢迎有任何问题一起交流讨论!

2赞