mirror of
https://github.com/HappyLifeOk/cc-3-8-x-mcp.git
synced 2026-08-20 21:47:07 +00:00
[cli] 新增: add-spine-socket op(绑定 Spine Socket 到节点)
This commit is contained in:
@@ -70,6 +70,7 @@ node extensions/cc-3-8-x-mcp/cli/bin/cocos-mcp-cli.js <command>
|
||||
|---|---|
|
||||
| 加节点 | `add-node` |
|
||||
| 加嵌套 prefab 实例(stub) | `add-nested-prefab`(parent + prefabUuid + name? + lpos?) |
|
||||
| 给 Spine 增加/更新 socket 绑定 | `add-spine-socket`(node + path + target;同 path 幂等更新 target) |
|
||||
| 替换嵌套 prefab 的 asset uuid(保留 stub 结构) | `replace-nested-prefab`(target + prefabUuid + clearOverrides?) |
|
||||
| 删节点 | `remove-node` |
|
||||
| 清悬空嵌套实例根(删了一半的 prefab 残留:父引用没了但根 PrefabInfo 登记还在,残留 asset 仍被加载 → 404)| `sync-nested-roots`(无参,重建根 nestedPrefabInstanceRoots) |
|
||||
|
||||
@@ -51,6 +51,7 @@ Supported ops:
|
||||
reorder-children # 调子节点顺序(影响渲染层级)
|
||||
bulk-set # 按 selector(byComponent/byNamePrefix/byNameRegex)一次改一批
|
||||
add-node / remove-node / clone-node
|
||||
add-spine-socket # 给 sp.Skeleton 增加/更新 socket 绑定
|
||||
add-component / set-component-ref # componentType 支持 @ccclass 名或压缩 classId
|
||||
# set-component-ref 的 refSubNode 可用字符串数组走多层嵌套 stub
|
||||
set-nested-component-field # 仅 stub 节点(嵌套 prefab)改组件字段
|
||||
|
||||
@@ -45,6 +45,7 @@ const { execSetSprite } = require('./ops/set-sprite.js');
|
||||
const { execSetNodeColor } = require('./ops/set-node-color.js');
|
||||
const { execReplaceNestedPrefab } = require('./ops/replace-nested-prefab.js');
|
||||
const { execAddNestedPrefab } = require('./ops/add-nested-prefab.js');
|
||||
const { execAddSpineSocket } = require('./ops/add-spine-socket.js');
|
||||
const { execResetOverrides } = require('./ops/reset-overrides.js');
|
||||
const { execEnsureMeta } = require('./ops/ensure-meta.js');
|
||||
const { execSyncNestedRoots } = require('./ops/sync-nested-roots.js');
|
||||
@@ -81,6 +82,7 @@ const OP_HANDLERS = {
|
||||
'set-node-color': execSetNodeColor,
|
||||
'replace-nested-prefab': execReplaceNestedPrefab,
|
||||
'add-nested-prefab': execAddNestedPrefab,
|
||||
'add-spine-socket': execAddSpineSocket,
|
||||
'reset-overrides': execResetOverrides,
|
||||
'ensure-meta': execEnsureMeta,
|
||||
'sync-nested-roots': execSyncNestedRoots,
|
||||
|
||||
@@ -88,6 +88,7 @@ const T = {
|
||||
constraintNum: 'number',
|
||||
placeholder: 'string',
|
||||
string: 'string',
|
||||
path: 'string',
|
||||
labelNode: 'string',
|
||||
spriteNode: 'string',
|
||||
subNode: 'any', // string | string[]
|
||||
@@ -129,6 +130,7 @@ const SCHEMAS = {
|
||||
'set-node-color': { required: ['node'], optional: ['r', 'g', 'b', 'a'] },
|
||||
'replace-nested-prefab': { required: ['target', 'prefabUuid'], optional: ['clearOverrides'] },
|
||||
'add-nested-prefab': { required: ['parent', 'prefabUuid'], optional: ['name', 'lpos'] },
|
||||
'add-spine-socket': { required: ['node', 'path', 'target'], optional: [] },
|
||||
'reset-overrides': { required: ['node'], optional: ['property', 'componentType', 'subNode', 'all'] },
|
||||
// ensure-meta: 给 .ts/.json 文件创建 .meta(v4 uuid),让后续 className → classId 查表能命中
|
||||
'ensure-meta': { required: ['path'], optional: [], typeOverrides: { path: 'string' } },
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// add-spine-socket: 给普通节点上的 sp.Skeleton 增加 / 更新 Spine socket 绑定
|
||||
// op: { op:'add-spine-socket', node, path, target }
|
||||
//
|
||||
// - node: 挂 sp.Skeleton 的节点
|
||||
// - path: Spine socket path,例如 "root/zk/tou2"
|
||||
// - target: 要绑定到该 socket 的 cc.Node
|
||||
// - 幂等:同 path 已存在时只更新 target,不新增重复 socket 对象
|
||||
|
||||
'use strict';
|
||||
|
||||
const { makeSpineSocket } = require('../../primitives.js');
|
||||
const { isStub, resolveNode, findComponent } = require('../helpers.js');
|
||||
|
||||
function execAddSpineSocket(prefabData, op) {
|
||||
const { elements } = prefabData;
|
||||
const { node: nodeSelector, path, target: targetSelector } = op;
|
||||
|
||||
if (typeof path !== 'string' || path.length === 0) {
|
||||
throw new Error(`editPrefab [add-spine-socket]: path 必须是非空字符串`);
|
||||
}
|
||||
|
||||
const { node, nodeId } = resolveNode(prefabData, nodeSelector, 'add-spine-socket');
|
||||
if (isStub(elements, node)) {
|
||||
throw new Error(`editPrefab [add-spine-socket]: 节点 "${node._name}" 是 stub 代理,不支持直接改子 prefab 的 sp.Skeleton`);
|
||||
}
|
||||
|
||||
const skeleton = findComponent(elements, node, 'sp.Skeleton');
|
||||
if (!skeleton) {
|
||||
throw new Error(`editPrefab [add-spine-socket]: 节点 "${node._name}" 上找不到 sp.Skeleton 组件`);
|
||||
}
|
||||
|
||||
const { nodeId: targetId } = resolveNode(prefabData, targetSelector, 'add-spine-socket target');
|
||||
|
||||
if (!Array.isArray(skeleton._sockets)) skeleton._sockets = [];
|
||||
for (const socketRef of skeleton._sockets) {
|
||||
if (!socketRef || typeof socketRef.__id__ !== 'number') continue;
|
||||
const socket = elements[socketRef.__id__];
|
||||
if (socket && socket.__type__ === 'sp.Skeleton.SpineSocket' && socket.path === path) {
|
||||
socket.target = { __id__: targetId };
|
||||
return nodeId;
|
||||
}
|
||||
}
|
||||
|
||||
const socketId = elements.length;
|
||||
elements.push(makeSpineSocket({ path, targetId }));
|
||||
skeleton._sockets.push({ __id__: socketId });
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
module.exports = { execAddSpineSocket };
|
||||
@@ -391,6 +391,22 @@ function makeSpSkeleton(opts) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造 sp.Skeleton.SpineSocket 裸对象。
|
||||
* @param {object} opts
|
||||
* @param {string} opts.path - Spine bone/slot path,例如 root/zk/tou2
|
||||
* @param {number} opts.targetId - 绑定的 cc.Node __id__
|
||||
* @returns {object}
|
||||
*/
|
||||
function makeSpineSocket(opts) {
|
||||
const { path, targetId } = opts;
|
||||
return {
|
||||
__type__: 'sp.Skeleton.SpineSocket',
|
||||
path,
|
||||
target: ref(targetId),
|
||||
};
|
||||
}
|
||||
|
||||
// ─────────────────────────────────────────────
|
||||
// cc.PrefabInfo / cc.CompPrefabInfo
|
||||
// ─────────────────────────────────────────────
|
||||
@@ -469,6 +485,7 @@ module.exports = {
|
||||
makeLabel,
|
||||
makeWidget,
|
||||
makeSpSkeleton,
|
||||
makeSpineSocket,
|
||||
// Prefab 元信息
|
||||
makePrefabInfo,
|
||||
makeCompPrefabInfo,
|
||||
|
||||
@@ -360,6 +360,7 @@ stub 节点(嵌套 prefab 实例)在 prefab JSON 里 `_name = ""`(空字
|
||||
| op | 参数 | 说明 |
|
||||
|---|---|---|
|
||||
| `add-node` | `parent`, `node: {name, lpos?, active?, components?, width?, height?, anchor?}` | 新增 cc.Node;parent 是 stub 时走 mountedChildren。`components: ["UITransform"]` 自动建 UITransform |
|
||||
| `add-spine-socket` | `node`, `path`, `target` | 给普通节点上的 `sp.Skeleton` 新增 / 更新 `sp.Skeleton.SpineSocket`。`path` 是 Spine socket path(如 `root/zk/tou2`),`target` 是绑定节点;同 path 幂等更新 target,不重复追加 |
|
||||
| `remove-node` | `target` | 从父节点移除引用;元素本身保留(orphan),保持其他 `__id__` 稳定 |
|
||||
| `sync-nested-roots` | (无) | 重建根 `PrefabInfo.nestedPrefabInstanceRoots`,剔除「删了一半」残留的悬空嵌套实例根(节点 `_parent` 已移除但根登记残留 → 残留嵌套 prefab 的 asset 仍被当依赖加载,运行时 404)。只重写该数组,不删 elements、不动其他 `__id__`、不产生 null 槽;被孤立的残留对象成为不可达 orphan。复用 remove-node 内部同名逻辑 |
|
||||
| `clone-node` | `source`, `parent`, `name` | 深拷贝整棵子树,分配新 `__id__` + 新 fileId |
|
||||
|
||||
Reference in New Issue
Block a user