Cocos Creator 发布到微信小游戏的资源管理

本文由本人简书搬迁至此,并做小幅修改。

环境:Cocos Creator v1.9.1; 微信web开发者工具 v1.02.0808300,线上基础调试库 1.9.92。


以下,ccc指cocos creator。资源均指Texture、Audio等非Prefab和场景的原生资源。

1. ccc resources下的资源会被全部放入小程序 res/raw-assets/resources 对应目录下。

2. ccc 不在resources下,但直接被“参与构建的Scene”引用的资源, 会被放入小程序res/raw-assets/对应目录下。
注意:
如果Scene为构建时正在打开的MainScene, 该Scene会被强制参与构建。
如果Scene在resources下,该Scene会被强制参与构建。

3. ccc 参与构建的Scene(实际是个json文件。可用文本编辑器打开看)会被 将其内容以json文件的形式放入res/import目录下。

4. ccc 不在resources下,但被reources下prefab引用的资源, 会被放入小程序res/raw-assets/对应目录下。

5. ccc resources下的prefab(实际是个json文件。可用文本编辑器打开看)会被 将其内容以json文件的形式放入res/import目录下。

6. ccc 不在resources下,但直接被“参与构建的Scene”引用的prefab会被 将其内容以json文件的形式放入res/import目录下。

7. ccc 不在resources下,但被上面第6条中prefab引用的资源,会被放入小程序res/raw-assets/对应目录下。

资源、Prefab及场景的.meta文件的内容,会被以json的形式代替存储。
该json文件的命名规则是:原.meta文件中subMetas字段下的资源的uuid。
该json文件被放入小程序的 res/import目录下。(按文件名的前两位,分文件夹存储)。

其实和Unity发布到各原生平台是一样的。游戏中的资源出现在游戏中,只可能通过两种方式:
1.被参与构建的场景中直接或间接引用,当场景加载时出现。
2.被resources文件下的文件直接或间接引用, 当引用资源的文件被 resources.load() 到场景中时候出现。

注意:所有被从ccc放入微信小游戏res的资源文件,都可以在小程序 src/setting.js 中看到。


ccc->小游戏的资源管理方式:

小程序res文件夹大于4M时预览,会提示Error:代码包大小为xxxxkb,上限为4096kb,请删除文件后重试。

其中ccc发布自动生成的 cocos2d-js 就有2.96M。 这个文件可以在ccc/项目/项目设置/模块设置中删减用不到的模块后减小。
官方文档-发布到微信小游戏平台
http://docs.cocos.com/creator/manual/zh/publish/publish-wechatgame.html

按照文档,
1.构建时,勾选 md5Cache 功能。
2.将小游戏发布包中的 res 文件夹完整得上传到服务器。
3.删除发布包内的 res 文件夹。
4.在 game.js 中,找到对应代码段并添加 REMOTE_SERVER_ROOT 的设置。这里也可在ccc的构建发布为WechatGame时,填“远程服务器地址”处。

require('libs/wx-downloader.js');
wxDownloader.REMOTE_SERVER_ROOT = 'http://www.nratel.com/myfiles/';

按此方法, 包内将不包含任何res文件,只剩代码文件。
实际在手机中运行:
第一次打开:Main场景出来前有一点时间。
之后打开:很流畅,没有下载加载感觉。


有个疑问?按照此方式,是在游戏打开时一次性下载完了所有远程res,还是用到的本地没有才下载?

ccc 在小游戏中下载并保存远程资源的逻辑写在 libs/wx-downloader.js 中。

简单测试1:
一个空场景, 只引用一张图片,
在wx-downloader.js的 nextPipe、readText、readFromLocal、ensureDirFor、downloadRemoteFile方法中各加一句log。来验证资源加载的过程。

本地不存在时, 从远程加载:

本地存在时, 直接从本地读取:

可以看出, 每次加载场景和图片时都是先调用readFromLocal()在本地读取, 如果成功就直接使用,如果失败就调用downloadRemoteFile()从远程下载。

简单测试2:
在wx-downloader.js的 downloadRemoteFile 方法中第二行加个log,来验证资源加载时机:

cc.log("downloadRemoteFile, relatUrl: " + relatUrl);

主场景如下,点击三个按钮时,加载各自对应的引用几个图标资源的界面。
主场景打开时:
从远程服务器下载了MainScene对应的json文件。以及MainScene引用的图片资源。

依次点击三个按钮:
依次在按钮点击时,从远程服务器下载了各自界面Prefab对应的json文件。以及Prefab引用的图片资源。

也就是说,资源是按需加载的。

  1. 在ccc中切换场景时,通过Https下载资源到内存后加载使用,最后保存到本地。
  2. 调用cc.loader.loadRes 加载prefab时,通过Https下载资源到内存后加载使用,最后保存到本地。

这也解释了ccc 为什么只提供异步的cc.loader.loadRes (和Unity不同)
正是因为在h5或小游戏环境中, cc.loader.loadRes是按需的,包含了 下载 和 加载 的过程。。下载是异步的。所以cc.loader.loadRes只能是异步的。

按照ccc的资源管理的思路。考虑:

  1. 将所有发布到微信res目录的文件全部放在远程服务器。
  2. Main场景引用的资源应尽可能的少(保证打开游戏到界面展示出来的速度),最好只包含一个Loading界面。
  3. 在Loading界面中使用 cc.loader.loadRes 或 cc.loader.loadResDir 将游戏的json配置文件以及需要即时使用的资源文件 预下载。
  4. 在某些地方使用 “延迟加载依赖的资源”:
    场景和Prefab可勾选的选项。勾选后,被依赖的资源会在场景和Prefab使用后加载。 详见 官方文档-延迟加载依赖的资源 最底下。

资源版本如何管理?
首先,微信不允许代码热更新,每次代码改变都需要重新提审。这里主要说资源的更新和管理。
按照上边的思路进行实现,最后,资源都放在远程服务器上,正因为如此,资源可以在不重新提审游戏包的情况下进行有限的更新操作(只能同名替换, 所有资源名都注册在src/setting.js中)。 需要注意,这样的“热更新”是有缺陷的:因为缓存机制,只有新用户才有用,老用户并不会下载与本地缓存同名的新资源。

接下来,很重要的一点是,如何保证 开发、提审和线上 的资源互不影响, 并且能够支持上边的热更(资源替换)?
方案: 在每次提审时打项目分支。资源路径拼上分支版本。 如图。

这样, 最终 内网开发版(体验版),外网提审版(体验版),外网线上版(正式版)可以有三个独立的入口,资源也互不影响。

最后,根据 小游戏更新机制 加上这段代码,让游戏启动时先进行检查更新。

--------------------------------------------------NRatel割--------------------------------------------------

NRatel
转载请说明出处,谢谢

猜你喜欢

转载自blog.csdn.net/NRatel/article/details/83663262