prefab
- 开发模式下
[
{
"__type__": "cc.Prefab",
"_name": "",
"_objFlags": 0,
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"asyncLoadAssets": false,
"readonly": false
},
{
"__type__": "cc.Node",
"_name": "New Node",
"_objFlags": 0,
"_parent": null,
"_children": [],
"_active": true,
"_components": [],
"_prefab": {
"__id__": 2
},
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 0,
"height": 0
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": ""
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "",
"sync": false
}
]
最终序列化的json就是上边的数据
function deserialize(json, options) {
var classFinder, missingClass;
false;
classFinder = cc._MissingScript.safeFindClass;
var pool = null;
false;
var _require = require("../platform/deserialize-compiled"), deserializeForCompiled = _require["default"];
var deserializeForEditor = require("../platform/deserialize-editor");
pool = deserializeForCompiled.isCompiledJson(json) ? deserializeForCompiled.Details.pool : deserializeForEditor.Details.pool;
var tdInfo = pool.get();
var asset;
try {
asset = cc.deserialize(json, tdInfo, {
classFinder: classFinder,
customEnv: options
});
} catch (e) {
pool.put(tdInfo);
throw e;
}
false;
var uuidList = tdInfo.uuidList;
var objList = tdInfo.uuidObjList;
var propList = tdInfo.uuidPropList;
var depends = [];
for (var i = 0; i < uuidList.length; i++) {
var dependUuid = uuidList[i];
depends[i] = {
uuid: helper.decodeUuid(dependUuid),
owner: objList[i],
prop: propList[i]
};
}
asset.__depends__ = depends;
asset._native && (asset.__nativeDepend__ = true);
pool.put(tdInfo);
return asset;
}
- 构建后
[
1,
["b6C9ZaXKNCT6erXsO4zEBN"],
["asset","root","data"],
[
["cc.Prefab",["_name"],2],
["cc.Node",["_name","_prefab"],2,4],
["cc.PrefabInfo",["root","asset"],3,1,6]
],
[
[0,0,2],
[1,0,1,2],
[2,0,1,1]
],
[
[0,"New Node"],
[1,"New Node",[2,-1,0]]
],
0,
[0,1,1,0,2,1,1],
[0],
[0],
[0]
]
判断图片的扩展名
会根据id置换出来对应的纹理格式
预览模式下纹理是单文件传递过来的
所以无论你怎么排查上层的链路数据,你发现他都是上边的
但是在构建后,数据变成了
被包裹到了array[5]里面,追踪源码发现,最终也是对array[5]进行了解析
所以获取纹理的格式,直接取array[5][0]作为key就行, 然后直接取第一个元素
主要到array[5]也是一个array,详细的逻辑参考parseInstances的实现,里面有详细的解释,暂时没精力分析
至于array的其他数组数据的含义,有时间再研究
json类型
[
1, // 0 version,会被替换为options的数据
0, // 1
0, // 2
[
[
"cc.JsonAsset", // 会被替换成对应的构造函数
[
"_name",
"json"
], // keys
1 // classTypeOffset
]
], // 3 classes
[
[
0,
0,
1,
3 // maskTypeOffset
]
], // 4 masks
[
[
0,
"json",
{}
]
],// instances的数据
0,// instanceTypes
0,
[],
[],
[]
]
json走的是通用的序列化
arr[3] classes 的数据解析
走的都是正常的序列化逻辑,不想再将这个逻辑搬运过来了,本来不同的版本还可能存在差异,所以,直接将cocos的代码改下,导出deserialize函数重新编译,然后需要一个运行环境,发现jsb有对window做适配,而单纯的nodejs环境是没有window的,
redirect
最终redirect的数据结构如下
const asset = {
uuid:"", // 这个资源的uuid
redirect:"internal",// 这个资源所在的bundle
}
引擎中关于redirect的解析逻辑
if (bundles.has(item.bundle)) {
var config = bundles.get(item.bundle)._config;
var info = config.getAssetInfo(uuid);
if (info && info.redirect) {// 是否为重定向的资源
if (!bundles.has(info.redirect)) { // 检查是否加载了重定向的bundle
throw new Error("Please load bundle " + info.redirect + " first");
}
config = bundles.get(info.redirect)._config;// 获取重定向bundle的配置
info = config.getAssetInfo(uuid);// 从重定向的bundle中获取资源信息
}
out.config = config;
out.info = info;
}
这也解释了,engine要求使用bundle的资源之前,必须加载依赖的bundle
pack
加载pack的逻辑
load: function load(item, options, onComplete) {
// 如果没被打包进去,就直接下载
if (item.isNative || !item.info || !item.info.packs) return downloader.download(item.id, item.url, item.ext, item.options, onComplete);
if (files.has(item.id)) return onComplete(null, files.get(item.id));
var packs = item.info.packs;// 被pack进去的信息
var pack = packs.find(isLoading);
if (pack) return _loading.get(pack.uuid).push({
onComplete: onComplete,
id: item.id
});
pack = packs[0];
_loading.add(pack.uuid, [ {
onComplete: onComplete,
id: item.id
} ]);
var url = cc.assetManager._transform(pack.uuid, {
ext: pack.ext,
bundle: item.config.name
});
// 下载pack的数据,也就是上图中的023c6ef0e
downloader.download(pack.uuid, url, pack.ext, item.options, (function(err, data) {
files.remove(pack.uuid);
err && cc.error(err.message, err.stack);
// 解开pack的数据
packManager.unpack(pack.packs, data, pack.ext, item.options, (function(err, result) {
if (!err) for (var id in result) files.add(id, result[id]);
var callbacks = _loading.remove(pack.uuid);
for (var i = 0, l = callbacks.length; i < l; i++) {
var cb = callbacks[i];
if (err) {
cb.onComplete(err);
continue;
}
var data = result[cb.id];
data ? cb.onComplete(null, data) : cb.onComplete(new Error("can not retrieve data from package"));
}
}));
}));
}
解析 pack data 的逻辑
unpackJson: function unpackJson(pack, json, options, onComplete) {
var out = js.createMap(true), err = null;
if (Array.isArray(json)) {
json = (0, _deserializeCompiled.unpackJSONs)(json, cc._MissingScript.safeFindClass);
json.length !== pack.length && cc.errorID(4915);
for (var i = 0; i < pack.length; i++) {
var key = pack[i] + "@import";
out[key] = json[i];
}
} else {
var textureType = js._getClassId(cc.Texture2D);
if (json.type === textureType) {
if (json.data) {
var datas = json.data.split("|");
datas.length !== pack.length && cc.errorID(4915);
for (var _i = 0; _i < pack.length; _i++) out[pack[_i] + "@import"] = (0, _deserializeCompiled.packCustomObjData)(textureType, datas[_i]);
}
} else {
err = new Error("unmatched type pack!");
out = null;
}
}
onComplete && onComplete(err, out);
}