mirror of
https://github.com/HappyLifeOk/cc-3-8-x-mcp.git
synced 2026-08-20 05:27:02 +00:00
[cli] 新增: 节点路径/名称查找支持 stub override 名
This commit is contained in:
@@ -76,6 +76,32 @@ function isStub(elements, node) {
|
||||
return !!(instance && instance.__type__ === 'cc.PrefabInstance');
|
||||
}
|
||||
|
||||
// ─── 获取 stub 节点的 override 显示名 ───────────────────────
|
||||
// stub 节点的 _name 通常为 undefined,真实显示名存在
|
||||
// PrefabInstance.propertyOverrides 中 propertyPath: ["_name"] 条目
|
||||
|
||||
function getStubOverrideName(elements, node) {
|
||||
if (!node || node.__type__ !== 'cc.Node') return null;
|
||||
const prefabRef = node._prefab;
|
||||
if (!prefabRef || typeof prefabRef.__id__ !== 'number') return null;
|
||||
const prefabInfo = elements[prefabRef.__id__];
|
||||
if (!prefabInfo || prefabInfo.__type__ !== 'cc.PrefabInfo') return null;
|
||||
const instanceRef = prefabInfo.instance;
|
||||
if (!instanceRef || typeof instanceRef.__id__ !== 'number') return null;
|
||||
const instance = elements[instanceRef.__id__];
|
||||
if (!instance || instance.__type__ !== 'cc.PrefabInstance') return null;
|
||||
|
||||
if (!Array.isArray(instance.propertyOverrides)) return null;
|
||||
for (const ovRef of instance.propertyOverrides) {
|
||||
if (typeof ovRef.__id__ !== 'number') continue;
|
||||
const ov = elements[ovRef.__id__];
|
||||
if (!ov || ov.__type__ !== 'CCPropertyOverrideInfo') continue;
|
||||
if (!Array.isArray(ov.propertyPath) || ov.propertyPath.length !== 1 || ov.propertyPath[0] !== '_name') continue;
|
||||
return ov.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ─── 引用相等查 __id__ ───────────────────────────────────────
|
||||
|
||||
function indexOfNode(elements, node) {
|
||||
@@ -123,8 +149,7 @@ function resolveNode(prefabData, nodeSelector, opDesc) {
|
||||
|
||||
// 按路径定位节点(DOM-like)
|
||||
// path 形如 "Canvas/Main/itemList",从根节点开始按 _name 逐级下钻
|
||||
// 每段必须命中 _children 中某个节点的 _name
|
||||
// 遇到 stub 节点时不下钻(stub _name 在 propertyOverrides 里,超出 cli 范围)
|
||||
// 每段必须命中 _children 中某个节点的 _name 或 stub override 名
|
||||
function resolveNodeByPath(prefabData, pathStr, opDesc) {
|
||||
const { elements, rootId, getRoot } = prefabData;
|
||||
const segments = pathStr.split('/').filter((s) => s.length > 0);
|
||||
@@ -147,8 +172,14 @@ function resolveNodeByPath(prefabData, pathStr, opDesc) {
|
||||
for (const cref of cur._children) {
|
||||
if (typeof cref.__id__ !== 'number') continue;
|
||||
const child = elements[cref.__id__];
|
||||
if (child && child._name === seg) {
|
||||
if (!child) continue;
|
||||
if (child._name === seg) {
|
||||
matches.push(cref.__id__);
|
||||
} else {
|
||||
const overrideName = getStubOverrideName(elements, child);
|
||||
if (overrideName === seg) {
|
||||
matches.push(cref.__id__);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matches.length === 0) {
|
||||
@@ -199,6 +230,7 @@ function findRootPrefabInfo(elements, rootNodeId) {
|
||||
module.exports = {
|
||||
normalizeComponentType,
|
||||
isStub,
|
||||
getStubOverrideName,
|
||||
indexOfNode,
|
||||
resolveNode,
|
||||
findComponent,
|
||||
|
||||
+25
-2
@@ -95,15 +95,38 @@ function parsePrefab(filePath) {
|
||||
}
|
||||
|
||||
// ─── findNodeByName ───────────────────────────────────────
|
||||
// 从根节点递归 DFS,返回第一个 _name 匹配的 cc.Node
|
||||
// 从根节点递归 DFS,返回第一个名称匹配的 cc.Node
|
||||
// 同时检查 _name 和 stub override 名(stub 的 _name 为 undefined,
|
||||
// 真实名在 PrefabInstance.propertyOverrides 的 _name 条目)
|
||||
function findNodeByName(name) {
|
||||
const root = getRoot();
|
||||
if (!root) return null;
|
||||
return _findByName(root, name, new Set([rootId]));
|
||||
}
|
||||
|
||||
function _getEffectiveName(node) {
|
||||
if (node._name !== undefined) return node._name;
|
||||
const prefabRef = node._prefab;
|
||||
if (!prefabRef || typeof prefabRef.__id__ !== 'number') return undefined;
|
||||
const pi = idIndex[prefabRef.__id__];
|
||||
if (!pi || pi.__type__ !== 'cc.PrefabInfo') return undefined;
|
||||
const instRef = pi.instance;
|
||||
if (!instRef || typeof instRef.__id__ !== 'number') return undefined;
|
||||
const inst = idIndex[instRef.__id__];
|
||||
if (!inst || inst.__type__ !== 'cc.PrefabInstance') return undefined;
|
||||
if (!Array.isArray(inst.propertyOverrides)) return undefined;
|
||||
for (const ovRef of inst.propertyOverrides) {
|
||||
if (typeof ovRef.__id__ !== 'number') continue;
|
||||
const ov = idIndex[ovRef.__id__];
|
||||
if (!ov || ov.__type__ !== 'CCPropertyOverrideInfo') continue;
|
||||
if (!Array.isArray(ov.propertyPath) || ov.propertyPath.length !== 1 || ov.propertyPath[0] !== '_name') continue;
|
||||
return ov.value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function _findByName(node, name, visited) {
|
||||
if (node._name === name) return node;
|
||||
if (_getEffectiveName(node) === name) return node;
|
||||
if (!Array.isArray(node._children)) return null;
|
||||
for (const childRef of node._children) {
|
||||
if (typeof childRef.__id__ !== 'number') continue;
|
||||
|
||||
Reference in New Issue
Block a user