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