告别微信小游戏启动场景黑屏,分享一个内置资源打包插件

我有个思路,在onBeforeBuildFinish的时候所有文件名都只是【uuid+格式】还没有md5,这个时候可以使用第三方库获取这些文件的md5值,最后在onBuildFinish的时候用【uuid+md5+格式】作为路径拷贝资源

还没实践过,你可以试试:grin:

堆栈有死循环

2.2.2
我的资源比较多
会造成堆栈溢出
可能是插件堆栈代码死循环了

我qq 339385266 方便交流

https://github.com/dylan465/plugin_internal_res_packer/commit/96fcd624d302222145d70b112c76c5948fce8bcc

2.1.3版本构建失败 报错信息:
62/62de3fde-45e2-4c0a-9770-3158ec028d74.dac95.ttf’
at fs.statSync (fs.js:973:11)
at Object.fs.statSync (ELECTRON_ASAR.js:298:16)
at Object.statSync (/Applications/CocosCreator.app/Contents/Resources/app.asar/node_modules/graceful-fs/polyfills.js:308:16)
at Object.copySync (/Applications/CocosCreator.app/Contents/Resources/app.asar/node_modules/fire-fs/node_modules/fs-extra/lib/copy-sync/copy-sync.js:21:84)
at copyFile (/Users/chengyoung/miniprogram/packages/plugin_internal_res_packer/main.js:51:6)
at copyAssetByUuid (/Users/chengyoung/miniprogram/packages/plugin_internal_res_packer/main.js:81:6)
at copyAssets (/Users/chengyoung/miniprogram/packages/plugin_internal_res_packer/main.js:92:6)
at copyAssets (/Users/chengyoung/miniprogram/packages/plugin_internal_res_packer/main.js:96:36)
at onBuildFinish (/Users/chengyoung/miniprogram/packages/plugin_internal_res_packer/main.js:124:3)
at /Applications/CocosCreator.app/Contents/Resources/app.asar/editor-framework/lib/share/polyfills.js:1:286
errno: -2,
code: ‘ENOENT’,
syscall: ‘stat’,
path: ‘/Users/chengyoung/miniprogram/build/wechatgame/res/raw-assets/62/62de3fde-45e2-4c0a-9770-3158ec028d74.dac95.ttf’ }
at then.e (/Applications/CocosCreator.app/Contents/Resources/app.asar/editor/lib/builder/index.js:1:885)
at
at process._tickDomainCallback (internal/process/next_tick.js:135:7)

看了下这里的字体文件是放在文件夹下面的


是因为这个原因导致构建失败的吗 要怎么修改一下呢

十分抱歉,ttf字体文件的构建后的路径有点特殊,晚点我会修复。
不过建议在启动场景不要引用ttf字体,因为会占用不少空间,毕竟只有宝贵的4M

666
2.2.2 可用
不过若是自己项目已经有一个定制构建的插件了,可能还得分个目录,不然怎么也识别不了,例如

这里可能会放版本号什么的

mark

只要我场景 嵌套了 一个 预制体 就会报错

Exception RangeError: Maximum call stack size exceeded

希望 题主 早日修复 !

我把自己的修改源码贴一下吧 onBuildFinish 方法 稍微修改 防止死循环的

function onBuildFinish(options, callback) {

let buildResults = options.buildResults;
let uuidList = [],myependUuids = [];

if (options.actualPlatform === 'wechatgame' && !options.debug && options.md5Cache) {
	function copyAssetByUuid(uuid) {
		let md5Array = getMd5ByUuidArray(buildResults, uuid);
		if (md5Array && md5Array.length > 0) {
			let srcArray = getFilePathArray(buildResults, Path.join(options.dest, 'res'), uuid, md5Array);
			let dstArray = getFilePathArray(buildResults, Path.join(options.dest, 'res_internal'), uuid, md5Array);
			for (let index = 0; index < srcArray.length; index++) {
				const src = srcArray[index];
				const dst = dstArray[index];
				copyFile(src, dst);
			}
		}
		uuidList.push(uuid);
	}

	function copyAssets(uuids) {
		myependUuids.push(uuids);
		for (let i = 0; i < uuids.length; ++i) {
			let uuid = uuids[i];
			let asset = buildResults._buildAssets[uuid];
			if (asset && buildResults.getAssetType(uuid) != 'folder') {

				if(uuidList.indexOf(uuid)==-1){
					copyAssetByUuid(uuid);
				}

				// 依赖数据
				let asset = buildResults._buildAssets[uuid];
				if(asset && asset.dependUuids&&myependUuids.indexOf(asset.dependUuids)==-1){
					copyAssets(asset.dependUuids); // 递归依赖
				}
				// 合并数据
				let packedUuid = getUuidFromPackedAssets(buildResults, uuid);
				if(packedUuid&&uuidList.indexOf(packedUuid)==-1){
					copyAssetByUuid(packedUuid);
				}
			}
		}
	}

	function queryAssets(dbPath) {
		Editor.assetdb.queryAssets(dbPath, null, (err, assetInfos) => {
			if (!err) {
				let array = assetInfos.map(x => x.uuid);
				copyAssets(array);
			}
		});
	}

	// 打包引擎内置的effects和materials
	queryAssets('db://internal/resources/**/*');

	// 打包启动场景资源

	// 方法1:读路径
	// queryAssets('db://assets/Scene/LaunchScene.fire');

	queryAssets('db://assets/scene/loading.fire');

	// 方法2:读配置
	var startSceneUuid = options.startScene;
	copyAssets([startSceneUuid]);

}
callback();

}`

厉害!总算有时间回来改bug了,现在github上面更新了,感谢支持:p

Cocos Creator 微信小游戏内置资源打包插件

插件功能:使用Cocos Creator构建微信小游戏项目时,会自动打包指定必要的内置资源到首包。有效解决启动场景因网络延迟或加载失败而导致的黑屏/卡死问题。

解决的具体问题:

  1. 在玩家首次启动游戏时,加载启动场景/首屏会从远程加载资源,资源在下载过程会出现短暂的黑屏甚至卡死。
  2. 其他资源加载问题,比如Cocos Creator 2.2.0华为快游戏播放音频时会出现卡顿,把对应的音频文件夹打包到包里可以解决这个问题。

解决思路:

把启动场景所依赖的必要资源单独放在包里面(本地),其他资源放在服务器

使用方法:

  1. 把该插件文件夹拷贝到{项目根目录}/packages下,重启Cocos Creator生效。如果想全局所有项目使用该插件,把插件文件夹拷贝到 {用户名}/.CocosCreator/packages下。
  2. 构建微信小游戏项目,勾选MD5 cache,取消勾选调试模式(正式打包才启用该插件功能)
  3. 构建完成后,会多出一个res_internal文件夹,这个文件夹就是内置的资源。把原本res文件夹资源上传到服务器后,移除res文件夹,最后把res_internal重命名为res。

温馨提示:

微信官方限制首包最大为4M,所以启动场景占用的资源要尽量的小。建议使用独立的图集,不要依赖其他与启动场景无关的资源。如果对字体有要求也尽量不要放TTF文件,使用图字代替会更省资源。

扩展功能,如果你还想打包其他资源参考下面的例子

打包文件夹 queryAssets(‘db://assets/resources/sounds/**/*’);
打包具体文件 queryAssets(‘db://assets/RewardView.prefab’);

版本更新日志:

1.0.1

  1. 修复ttf字体文件拷贝路径错误的问题
  2. 修复asset互相依赖导致插件死循环

1.0.0

  1. 修复构建mp3等资源只拷贝了配置文件,没有拷贝资源本身的问题
1赞

大佬,问个问题, 这句话Cocos Creator初始化引擎时,会先加载内置资源文件夹effects和materials下的资源
假设首个场景没有用到effectmaterials其它资源,譬如变灰材质,等等,之类的这些筛选不出来的,请问这个有法子解决么

后来我把加载内置资源的功能移除掉了,现在是没有的,可以去github上看一下。因为考虑到原本就支持拷贝依赖的所有文件,里面已经包括内置资源了,没必要把所有内置资源放进去。

注意:Cocos Creator 2.4.0已经有Asset Bundle了,官方已经支持启动场景资源分离,新版本的小伙伴们请忽略这个插件。

我看了一下应该是最新的了,把这个功能移除了?你的意思是修改源码把对应的内置资源不要在启动的时候加载,而是游戏里面用到哪个就加载哪个,是这个意思吗

首个场景用到的2d-sprite那个材质是有包含在导出的res_internal里面,但其他内置的没有,但我发现游戏启动的时候就已经开始加载这些配置了

我意思是只加载了场景中依赖到的内置资源,像你说的置灰材质是没有放到res_internal里面的。游戏启动的时候引擎初始化会加载所有内置基础的material和effect资源的,放到res_internal是为了防止引擎加载内置资源失败而出现黑屏的情况