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 去获取

标签: none

添加新评论