ccc构建后的config.json结构
ccc构建后的config.json结构
/** 构建后的Bundle /** 构建后的Bundle config.json文件解析 */
interface BundleConfig {
// 包内资源列表 <资源uuid索引,<资源相对路径, 资源类型索引>>
paths: Record<string, [string, number]>;
// 类型数组 debug没有该字段;
types: string[];
// 资源uuid数组
uuids: string[];
// 场景 <场景url, 场景资源uuid索引>
scenes: Record<string, number>;
// 重新使用[uuid索引,重新使用次数]
redirect: number[];
// 依赖的bundle资源包名称
deps: string[];
// 合并的资源信息 {[合并的uuid] : [被合并的资源索引,...]}
packs: Record<string, number[]>;
// bundle名称
name: string;
// 资源前缀 比如cdn链接...
base: string;
// json文件夹
importBase: string;
// 原生资源信息
nativeBase: string;
// 是否是debug模式
debug: boolean;
// 是否zip压缩
isZip: boolean;
// 脚本是否加密
encrypted: boolean;
// 版本信息, 选择md5配置的时候
versions: {
// [资源uuid索引, md5, 资源uuid索引, md5,...],
import: any[];
// [资源uuid索引, md5, 资源uuid索引, md5,...]
native: any[];
}
}
interface BundleConfigDebug {
// 包内资源列表 <资源uuid, [资源相对路径, 资源类型]>
paths: Record<string, [string, string]>;
// 资源uuid数组
uuids: string[];
// 场景 <场景url, 场景uuid>
scenes: Record<string, string>;
// 重新使用[uuid,重新使用次数]
redirect: any[];
// 依赖的bundle资源包名称
deps: string[];
// 合并的资源信息 {[合并的uuid] : [被合并的资源uuid,...]}
packs: Record<string, string[]>;
// bundle名称
name: string;
// 资源前缀 比如cdn链接...
base: string;
// json文件夹
importBase: string;
// 原生资源信息
nativeBase: string;
// 是否是debug模式
debug: boolean;
// 是否zip压缩
isZip: boolean;
// 脚本是否加密
encrypted: boolean;
// 版本信息, 选择md5配置的时候
versions: {
// [资源uuid, md5, 资源uuid, md5,...],
import: string[];
// [资源uuid, md5, 资源uuid, md5,...]
native: string[];
}
}
interface BundleConfigAsset {
uuid: string;
path: string;
type: string;
}文件解析 */
interface BundleConfig {
// 包内资源列表 <资源uuid索引,<资源相对路径, 资源类型索引>>
paths: Record<string, [string, number]>;
// 类型数组 debug没有该字段;
types: string[];
// 资源uuid数组
uuids: string[];
// 场景 <场景url, 场景资源uuid索引>
scenes: Record<string, number>;
// 重新使用[uuid索引,重新使用次数]
redirect: number[];
// 依赖的bundle资源包名称
deps: string[];
// 合并的资源信息 {[合并的uuid] : [被合并的资源索引,...]}
packs: Record<string, number[]>;
// bundle名称
name: string;
// 资源前缀 比如cdn链接...
base: string;
// json文件夹
importBase: string;
// 原生资源信息
nativeBase: string;
// 是否是debug模式
debug: boolean;
// 是否zip压缩
isZip: boolean;
// 脚本是否加密
encrypted: boolean;
// 版本信息, 选择md5配置的时候
versions: {
// [资源uuid索引, md5, 资源uuid索引, md5,...],
import: any[];
// [资源uuid索引, md5, 资源uuid索引, md5,...]
native: any[];
}
}
interface BundleConfigDebug {
// 包内资源列表 <资源uuid, [资源相对路径, 资源类型]>
paths: Record<string, [string, string]>;
// 资源uuid数组
uuids: string[];
// 场景 <场景url, 场景uuid>
scenes: Record<string, string>;
// 重新使用[uuid,重新使用次数]
redirect: any[];
// 依赖的bundle资源包名称
deps: string[];
// 合并的资源信息 {[合并的uuid] : [被合并的资源uuid,...]}
packs: Record<string, string[]>;
// bundle名称
name: string;
// 资源前缀 比如cdn链接...
base: string;
// json文件夹
importBase: string;
// 原生资源信息
nativeBase: string;
// 是否是debug模式
debug: boolean;
// 是否zip压缩
isZip: boolean;
// 脚本是否加密
encrypted: boolean;
// 版本信息, 选择md5配置的时候
versions: {
// [资源uuid, md5, 资源uuid, md5,...],
import: string[];
// [资源uuid, md5, 资源uuid, md5,...]
native: string[];
}
}
interface BundleConfigAsset {
uuid: string;
path: string;
type: string;
}
一、 方法1:
我这边是通过进入游戏loadDir把某个目录下所有资源拿出来,然后可以看到所有uuid打包后的路径,与uuid一一对应的map格式存下来,生成一个json,然后写个脚本放在打包前的工程,根据目录下的meta文件对应的uuid找到刚才打包后的路径,盖过去。
二、 方法2:
Editor.Utils.UuidUtils
/**
* 获取uuid资源所在bundle的目录
* @param {string} uuid
* @returns {string}
*/
EditorUtil.uuid2path = function (uuid) {
return uuid.substr(0, 2) + "/" + uuid;
}
/**
* 获取uuid对应的资源所在的文件夹
* @param {string} uuid
* @returns {string}
*/
EditorUtil.uuiddir = function (uuid) {
return uuid.substr(0, 2)
}
/**
* 解码uuid
* @param {string} uuid
* @returns {string}
*/
EditorUtil.decompressUuid = function (uuid) {
return Editor.Utils.UuidUtils.decompressUuid(uuid);
}
/**
* 编码uuid
* @param {string} uuid
* @returns {string}
*/
EditorUtil.compressUuid = function (uuid) {
return Editor.Utils.UuidUtils.compressUuid(uuid, true);
}
2.x的可以用Editor.Utils.UuidUtils.decompressUuid(uid);解uuid
或者直接在,Creaor里面打开开发者工具,执行下面的命令
Editor.Utils.UuidUtils.decompressUuid('33OApMXptPLIf5Frt3uYvp')
"33380a4c-5e9b-4f2c-87f9-16bb77b98be9"
三、3.x版本
cc.assetManager.utils.decodeUuid可以解uuid
四、setting.js中的属性
(1)groupList 是分组表,collisionMatrix 是碰撞表
(2)rawAssets 字面意思是生资源、未加工过的资源,一般是图片、声音、预制、二进制文件;rawAssets下assets字段的各个属性都是数字类型的文本,代表的是setting.js文件最后的uuids数组的索引,加载的时候main.js会把这个数字替换为具体的uuid;比如这里assets下的属性"0"表示的是uuids里面的“dfjxSz6kJAyLAOXioGjgk3”。想查看这个uuid的具体内容,可以在Creaor里面打开开发者工具,然后把这个uuid解压为正常的uuid,再在项目的资源库里面搜索,就能找到这个uuid对应的资源。
可以看到这个文件是项目里面的“resources/Prefab/root.prefab”文件。
assets属性的值是项目resources 文件夹里面文件路径和资源类型;资源类型用数字标记,这个数字标记是下面的assetTypes数组的索引。比如这里的0代表下面assetTypes里的cc.Prefab。
(3) assetTypes 是资源类型数组,比如预制、音效、文本、JSON、二进制等等。这个数组是根据当前项目resources目录下存在的资源类型生成的,每一次生成的数组顺序可能是不一样的。公司项目的assetTypes 数组是这样的:
(4)jsList :导入的js插件列表,每个值是js插件的路径;当前项目没有导入js插件,所以没有这个字段。公司项目的jsList是这样的:
(5)launchScene:启动场景的路径
(6) scenes:当前项目的所有场景信息列表;这个列表里面的每个对象存储了场景的路径和场景的uuid索引,这个索引和其他地方的uuid索引一样,都是下面uuids列表的下标。找到uuid然后解压为未压缩的uuid,就能在项目的资源库里面找到这个场景的json文件了,
(7)packedAssets:打包的资源;Creator 会把一些json文件合并到一个json里面,能减少网络请求,提高效率。这个属性存储的就是打包信息。packedAssets下的字段名称是josn文件名称,可以在构建目录的import文件夹里面找到。packedAssets下的字段的值保存了这个json文件包含的其他json文件的uuid。同理,如果这里的uuid是数字类型,那么可以在uuids列表里面用这个数字做下标找到具体的uuid值。如果这里的uuid不是数字,那么这个json文件保存的一般是多个图片的贴图属性,比如这里的:
“0cfd22b7a”: [“6aoKpq6+5BVaCIpoemqt7E”, “a8Anh32NZGRZegUtSgEj26”]
在构建目录里面搜索“0cfd22b7a”,打开后可以看到这两个uuid对应图片的贴图属性,两张图片的属性是用“|”分割开的,截图如下:
解压uuid “6aoKpq6+5BVaCIpoemqt7E”,
packedAssets下字段的生成规则暂时还不知道,谁要知道说一下就好了。
(8)md5AssetsMap:如果构建时选中了“MD5缓存”和“合并初始场景依赖的所有JSON文件”选项,这个对象下会有值。这个对象存储的是构建后每个文件的名称信息。他的子对象表示文件夹,目前只有import(本文类文件,后缀都是json,比如动画anim、场景fire文件和txt文件都会转为json格式存在这里)和"raw-assets"(二进制类(生的)文件,比如图片和音频)。子对象数组中,第0个值和偶数下标上的值表示原始文件名称,奇数下标上的值表示文件的md5后缀,把这两个值合起来,就能找到对应的文件。如果下标上的值为数字类型,则需把这个数字作为下标,在setting.js的uuids数组中找到具体的uuid,然后解压uuid,解压后的uuid才是文件名称。
(9) bundleVers是window._CCSettings下设置的对应分包的config.xxx.config的md5的值。
uuids中下标为2的uuid是"16nEH41pZDmr84oqQYyUG6",解压:
Editor.Utils.UuidUtils.decompressUuid(“16nEH41pZDmr84oqQYyUG6”)
“169c41f8-d696-439a-bf38-a2a418c941ba”
三、不用库直接处理uuid
// ------------decode-uuid
const BASE64_KEYS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
const values = new Array(123); // max char code in base64Keys
for (let i = 0; i < 123; ++i) { values[i] = 64; } // fill with placeholder('=') index
for (let i = 0; i < 64; ++i) { values[BASE64_KEYS.charCodeAt(i)] = i; }
// decoded value indexed by base64 char code
const BASE64_VALUES = values;
const HexChars = '0123456789abcdef'.split('');
const _t = ['', '', '', ''];
const UuidTemplate = _t.concat(_t, '-', _t, '-', _t, '-', _t, '-', _t, _t, _t);
const Indices = UuidTemplate.map((x, i) => x === '-' ? NaN : i).filter(isFinite);
const uuid = '33OApMXptPLIf5Frt3uYvp';
const originalUuid = decodeUuid(uuid); // fc991dd7-0033-4b80-9d41-c8a86a702e59
console.log('originalUuid',originalUuid);
// 解压uuid
function decodeUuid(base64) {
const strs = base64.split('@');
const uuid = strs[0];
if (uuid.length !== 22) {
return base64;
}
UuidTemplate[0] = base64[0];
UuidTemplate[1] = base64[1];
for (let i = 2, j = 2; i < 22; i += 2) {
const lhs = BASE64_VALUES[base64.charCodeAt(i)];
const rhs = BASE64_VALUES[base64.charCodeAt(i + 1)];
UuidTemplate[Indices[j++]] = HexChars[lhs >> 2];
UuidTemplate[Indices[j++]] = HexChars[((lhs & 3) << 2) | rhs >> 4];
UuidTemplate[Indices[j++]] = HexChars[rhs & 0xF];
}
return base64.replace(uuid, UuidTemplate.join(''));
}
let HexMap = {}
{
for (let i = 0; i < HexChars.length; i++) {
let char = HexChars[i]
HexMap[char] = i
}
}
// 压缩uuid
function compressUuid(fullUuid) {
const strs = fullUuid.split('@');
const uuid = strs[0];
if (uuid.length !== 36) {
return fullUuid;
}
let zipUuid = []
zipUuid[0] = uuid[0];
zipUuid[1] = uuid[1];
let cleanUuid = uuid.replace('-', '').replace('-', '').replace('-', '').replace('-', '')
for (let i = 2, j = 2; i < 32; i += 3) {
const left = HexMap[String.fromCharCode(cleanUuid.charCodeAt(i))];
const mid = HexMap[String.fromCharCode(cleanUuid.charCodeAt(i + 1))];
const right = HexMap[String.fromCharCode(cleanUuid.charCodeAt(i + 2))];
zipUuid[j++] = BASE64_KEYS[(left << 2) + (mid >> 2)]
zipUuid[j++] = BASE64_KEYS[((mid & 3) << 4) + right]
}
return fullUuid.replace(uuid, zipUuid.join(''));
}
console.log('uuid', compressUuid('33380a4c-5e9b-4f2c-87f9-16bb77b98be9'))
四、插件编写
let uuid = node.getComponent(cc.Sprite).spriteFrame._uuid
let path = Editor.remote.assetdb.uuidToFspath(uuid);
path == assets/resources/bgs.plist/pk_1_10.png
prefab 的话,可以通过 cc.find(‘New Node’)._prefab.asset._uuid 去获取