cocos2d-cli 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/{cocos-cli.js → cocos2d-cli.js} +17 -12
- package/package.json +3 -3
- package/src/commands/add-component.js +23 -54
- package/src/commands/add.js +31 -114
- package/src/commands/build.js +1 -1
- package/src/commands/create-scene.js +93 -467
- package/src/commands/get.js +5 -154
- package/src/commands/prefab-create.js +107 -379
- package/src/commands/remove.js +123 -59
- package/src/commands/set.js +12 -245
- package/src/commands/tree.js +4 -3
- package/src/lib/components/button.js +137 -0
- package/src/lib/components/camera.js +107 -0
- package/src/lib/components/canvas.js +89 -0
- package/src/lib/components/index.js +157 -0
- package/src/lib/components/label.js +120 -0
- package/src/lib/components/layout.js +110 -0
- package/src/lib/components/particle-system.js +160 -0
- package/src/lib/components/sprite.js +98 -0
- package/src/lib/components/widget.js +122 -0
- package/src/lib/fire-utils.js +58 -392
- package/src/lib/node-utils.js +359 -0
- package/src/lib/templates.js +212 -0
- package/src/lib/utils.js +139 -0
- package/src/commands/delete.js +0 -74
- package/src/commands/remove-component.js +0 -63
- package/src/lib/components.js +0 -404
|
@@ -14,7 +14,6 @@ const commands = {
|
|
|
14
14
|
add: '../src/commands/add',
|
|
15
15
|
'add-component': '../src/commands/add-component',
|
|
16
16
|
'remove': '../src/commands/remove',
|
|
17
|
-
delete: '../src/commands/delete',
|
|
18
17
|
build: '../src/commands/build',
|
|
19
18
|
'create-prefab': '../src/commands/prefab-create',
|
|
20
19
|
'create-scene': '../src/commands/create-scene'
|
|
@@ -34,11 +33,10 @@ Cocos Creator CLI - 场景/预制体操作工具集
|
|
|
34
33
|
set <场景.fire | 预制体.prefab> <索引> [选项] 修改节点属性
|
|
35
34
|
add <场景.fire | 预制体.prefab> <父索引> <名称> 添加节点
|
|
36
35
|
add-component <文件> <节点索引> <类型> 给节点添加组件
|
|
37
|
-
remove <文件> <索引>
|
|
38
|
-
delete <文件> <节点索引> 删除节点
|
|
36
|
+
remove <文件> <索引> [--component|--node] 删除节点或组件(自动检测类型)
|
|
39
37
|
build <项目目录> 构建组件映射
|
|
40
|
-
create-prefab <输出.prefab>
|
|
41
|
-
create-scene <输出.fire>
|
|
38
|
+
create-prefab [JSON文件] <输出.prefab> 创建预制体(不传JSON则创建默认)
|
|
39
|
+
create-scene <JSON文件> <输出.fire> 从JSON文件创建场景
|
|
42
40
|
|
|
43
41
|
选项:
|
|
44
42
|
--name=<名称> 修改节点名称
|
|
@@ -79,8 +77,13 @@ JSON 格式 (create-prefab / create-scene):
|
|
|
79
77
|
|
|
80
78
|
节点属性: name, width, height, x, y, color, opacity, anchorX, anchorY, rotation, scaleX, scaleY, active
|
|
81
79
|
|
|
80
|
+
组件写法:
|
|
81
|
+
简写: "sprite" 或 "label"
|
|
82
|
+
完整: { "type": "sprite", "sizeMode": 1 }
|
|
83
|
+
完整: { "type": "label", "string": "文本", "fontSize": 32, "color": "#fff" }
|
|
84
|
+
|
|
82
85
|
组件类型:
|
|
83
|
-
sprite -
|
|
86
|
+
sprite - 精灵(默认白色方块,节点设置什么颜色就显示什么颜色)
|
|
84
87
|
label - 文本,支持 string, fontSize, color(兼容)
|
|
85
88
|
button - 按钮,通常配合 sprite 使用才能看见
|
|
86
89
|
widget - 对齐,支持 top, bottom, left, right
|
|
@@ -92,7 +95,6 @@ JSON 格式 (create-prefab / create-scene):
|
|
|
92
95
|
注意:
|
|
93
96
|
- color 写在节点或 label 组件均可
|
|
94
97
|
- button 需要配合 sprite 才能看见按钮外观
|
|
95
|
-
- 必须通过 JSON 文件输入: type panel.json | cocos2d-cli create-prefab xxx.prefab
|
|
96
98
|
|
|
97
99
|
示例:
|
|
98
100
|
cocos2d-cli tree assets/main.fire
|
|
@@ -100,11 +102,14 @@ JSON 格式 (create-prefab / create-scene):
|
|
|
100
102
|
cocos2d-cli set assets/main.fire 8 --x=100 --y=200 --color=#ff0000
|
|
101
103
|
cocos2d-cli add assets/main.fire 5 NewSprite --type=sprite --x=100
|
|
102
104
|
|
|
103
|
-
# 从 JSON
|
|
104
|
-
|
|
105
|
+
# 从 JSON 文件创建场景
|
|
106
|
+
cocos2d-cli create-scene scene.json assets/scene.fire
|
|
107
|
+
|
|
108
|
+
# 从 JSON 文件创建预制体
|
|
109
|
+
cocos2d-cli create-prefab panel.json assets/panel.prefab
|
|
105
110
|
|
|
106
|
-
#
|
|
107
|
-
|
|
111
|
+
# 创建默认预制体(不传JSON)
|
|
112
|
+
cocos2d-cli create-prefab assets/NewNode.prefab
|
|
108
113
|
`);
|
|
109
114
|
}
|
|
110
115
|
|
|
@@ -132,4 +137,4 @@ try {
|
|
|
132
137
|
} catch (err) {
|
|
133
138
|
console.error(`命令执行失败: ${err.message}`);
|
|
134
139
|
process.exit(1);
|
|
135
|
-
}
|
|
140
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cocos2d-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Command-line tools for AI to read and manipulate Cocos Creator 2.4.x project scenes",
|
|
5
|
-
"main": "bin/
|
|
5
|
+
"main": "bin/cocos2d-cli.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"cocos2d-cli": "./bin/
|
|
7
|
+
"cocos2d-cli": "./bin/cocos2d-cli.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin",
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
const { loadScene, saveScene, buildMaps, findNodeIndex, refreshEditor } = require('../lib/fire-utils');
|
|
6
|
-
const {
|
|
6
|
+
const { outputError, outputSuccess, generateId } = require('../lib/utils');
|
|
7
|
+
const { createComponent } = require('../lib/components');
|
|
7
8
|
const fs = require('fs');
|
|
8
9
|
const path = require('path');
|
|
9
10
|
|
|
@@ -14,9 +15,7 @@ function loadScriptMap(projectPath) {
|
|
|
14
15
|
if (fs.existsSync(mapPath)) {
|
|
15
16
|
return JSON.parse(fs.readFileSync(mapPath, 'utf-8'));
|
|
16
17
|
}
|
|
17
|
-
} catch (e) {
|
|
18
|
-
// 忽略错误
|
|
19
|
-
}
|
|
18
|
+
} catch (e) {}
|
|
20
19
|
return {};
|
|
21
20
|
}
|
|
22
21
|
|
|
@@ -37,9 +36,7 @@ function createScriptComponent(scriptUuid, nodeId, scriptMap) {
|
|
|
37
36
|
|
|
38
37
|
function run(args) {
|
|
39
38
|
if (args.length < 3) {
|
|
40
|
-
|
|
41
|
-
error: '用法: cocos2.4 add-component <场景文件路径> <节点路径> <组件类型>'
|
|
42
|
-
}));
|
|
39
|
+
outputError('用法: cocos2d-cli add-component <场景文件路径> <节点路径> <组件类型>');
|
|
43
40
|
return;
|
|
44
41
|
}
|
|
45
42
|
|
|
@@ -51,58 +48,41 @@ function run(args) {
|
|
|
51
48
|
const data = loadScene(scenePath);
|
|
52
49
|
const { indexMap } = buildMaps(data);
|
|
53
50
|
|
|
54
|
-
// 查找节点
|
|
55
51
|
const nodeIndex = findNodeIndex(data, indexMap, nodeRef);
|
|
56
52
|
|
|
57
53
|
if (nodeIndex === null || !data[nodeIndex]) {
|
|
58
|
-
|
|
54
|
+
outputError(`找不到节点: ${nodeRef}`);
|
|
59
55
|
return;
|
|
60
56
|
}
|
|
61
57
|
|
|
62
58
|
const node = data[nodeIndex];
|
|
63
59
|
|
|
64
60
|
// 检查是否已有该类型组件
|
|
61
|
+
const ccType = 'cc.' + componentType.charAt(0).toUpperCase() + componentType.slice(1);
|
|
65
62
|
const existingComp = node._components?.find(comp => {
|
|
66
63
|
const compData = data[comp.__id__];
|
|
67
64
|
if (!compData) return false;
|
|
68
65
|
const compType = compData.__type__;
|
|
69
|
-
return compType === componentType || compType ===
|
|
66
|
+
return compType === componentType || compType === ccType;
|
|
70
67
|
});
|
|
71
68
|
|
|
72
69
|
if (existingComp) {
|
|
73
|
-
|
|
74
|
-
error: `节点 "${node._name}" 已有 ${componentType} 组件`,
|
|
75
|
-
nodeIndex,
|
|
76
|
-
nodeName: node._name
|
|
77
|
-
}));
|
|
70
|
+
outputError(`节点 "${node._name}" 已有 ${componentType} 组件`);
|
|
78
71
|
return;
|
|
79
72
|
}
|
|
80
73
|
|
|
81
|
-
// 加载脚本映射(从场景文件所在项目的 data 目录)
|
|
82
|
-
const projectPath = path.dirname(scenePath);
|
|
83
|
-
const scriptMap = loadScriptMap(projectPath);
|
|
84
|
-
|
|
85
|
-
// 创建组件
|
|
86
|
-
let componentData;
|
|
87
74
|
const compIndex = data.length;
|
|
75
|
+
let componentData;
|
|
88
76
|
|
|
89
|
-
//
|
|
90
|
-
|
|
77
|
+
// 尝试使用内置组件
|
|
78
|
+
componentData = createComponent(componentType, nodeIndex);
|
|
91
79
|
|
|
92
|
-
if (
|
|
93
|
-
//
|
|
94
|
-
const
|
|
95
|
-
|
|
80
|
+
if (!componentData) {
|
|
81
|
+
// 自定义脚本组件
|
|
82
|
+
const projectPath = path.dirname(scenePath);
|
|
83
|
+
const scriptMap = loadScriptMap(projectPath);
|
|
96
84
|
|
|
97
|
-
if (!componentData) {
|
|
98
|
-
console.log(JSON.stringify({ error: `不支持的组件类型: ${componentType}` }));
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
// 自定义脚本组件 - 查找脚本UUID
|
|
103
85
|
let scriptUuid = null;
|
|
104
|
-
|
|
105
|
-
// 在 scriptMap 中查找
|
|
106
86
|
for (const [uuid, info] of Object.entries(scriptMap)) {
|
|
107
87
|
if (info.name === componentType) {
|
|
108
88
|
scriptUuid = uuid;
|
|
@@ -110,42 +90,31 @@ function run(args) {
|
|
|
110
90
|
}
|
|
111
91
|
}
|
|
112
92
|
|
|
113
|
-
|
|
114
|
-
if (!scriptUuid) {
|
|
115
|
-
|
|
116
|
-
const uuidRegex = /^[a-f0-9-]{36}$/i;
|
|
117
|
-
if (uuidRegex.test(componentType)) {
|
|
118
|
-
scriptUuid = componentType;
|
|
119
|
-
}
|
|
93
|
+
const uuidRegex = /^[a-f0-9-]{36}$/i;
|
|
94
|
+
if (!scriptUuid && uuidRegex.test(componentType)) {
|
|
95
|
+
scriptUuid = componentType;
|
|
120
96
|
}
|
|
121
97
|
|
|
122
98
|
componentData = createScriptComponent(scriptUuid || componentType, nodeIndex, scriptMap);
|
|
123
99
|
}
|
|
124
100
|
|
|
125
|
-
// 添加组件到数组
|
|
126
101
|
data.push(componentData);
|
|
127
102
|
|
|
128
|
-
// 更新节点的 _components
|
|
129
103
|
if (!node._components) node._components = [];
|
|
130
104
|
node._components.push({ "__id__": compIndex });
|
|
131
105
|
|
|
132
|
-
// 保存场景
|
|
133
106
|
saveScene(scenePath, data);
|
|
134
|
-
|
|
135
|
-
// 触发编辑器刷新(传入场景路径以重新打开场景)
|
|
136
107
|
refreshEditor(scenePath);
|
|
137
108
|
|
|
138
|
-
|
|
139
|
-
success: true,
|
|
109
|
+
outputSuccess({
|
|
140
110
|
componentIndex: compIndex,
|
|
141
111
|
componentType: componentData.__type__,
|
|
142
112
|
nodeIndex,
|
|
143
|
-
nodeName: node._name
|
|
144
|
-
|
|
145
|
-
}, null, 2));
|
|
113
|
+
nodeName: node._name
|
|
114
|
+
});
|
|
146
115
|
} catch (err) {
|
|
147
|
-
|
|
116
|
+
outputError(err.message);
|
|
148
117
|
}
|
|
149
118
|
}
|
|
150
119
|
|
|
151
|
-
module.exports = { run };
|
|
120
|
+
module.exports = { run };
|
package/src/commands/add.js
CHANGED
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* add 命令 - 添加节点(支持场景和预制体)
|
|
3
|
-
*
|
|
4
|
-
* 预制体正确结构(深度优先遍历):
|
|
5
|
-
* 节点 → 子节点(递归) → 组件 → PrefabInfo
|
|
6
|
-
*
|
|
7
|
-
* 示例:
|
|
8
|
-
* [1] Node (根) _prefab -> [最后]
|
|
9
|
-
* [2] Node (子1) _prefab -> [6]
|
|
10
|
-
* [3] Node (孙) _prefab -> [5]
|
|
11
|
-
* [4] Component (孙的组件)
|
|
12
|
-
* [5] PrefabInfo (孙的)
|
|
13
|
-
* [6] Component (子1的组件)
|
|
14
|
-
* [7] PrefabInfo (子1的)
|
|
15
|
-
* [8] PrefabInfo (根的,在最后)
|
|
16
3
|
*/
|
|
17
4
|
|
|
18
|
-
const { loadScene, saveScene, buildMaps, refreshEditor, isPrefab, generateFileId } = require('../lib/fire-utils');
|
|
19
|
-
const {
|
|
5
|
+
const { loadScene, saveScene, buildMaps, refreshEditor, isPrefab, generateFileId, getPrefabRootIndex } = require('../lib/fire-utils');
|
|
6
|
+
const { parseOptions, outputError, outputSuccess } = require('../lib/utils');
|
|
7
|
+
const { createNodeData } = require('../lib/node-utils');
|
|
8
|
+
const { createComponent } = require('../lib/components');
|
|
20
9
|
|
|
21
10
|
/**
|
|
22
|
-
* 获取根节点 PrefabInfo
|
|
11
|
+
* 获取根节点 PrefabInfo 的索引
|
|
23
12
|
*/
|
|
24
13
|
function getRootPrefabInfoIndex(data) {
|
|
25
14
|
for (let i = data.length - 1; i >= 0; i--) {
|
|
@@ -32,7 +21,7 @@ function getRootPrefabInfoIndex(data) {
|
|
|
32
21
|
}
|
|
33
22
|
|
|
34
23
|
/**
|
|
35
|
-
*
|
|
24
|
+
* 获取节点子树的结束索引
|
|
36
25
|
*/
|
|
37
26
|
function getSubtreeEndIndex(data, nodeIndex) {
|
|
38
27
|
const node = data[nodeIndex];
|
|
@@ -40,7 +29,6 @@ function getSubtreeEndIndex(data, nodeIndex) {
|
|
|
40
29
|
|
|
41
30
|
let lastIndex = nodeIndex;
|
|
42
31
|
|
|
43
|
-
// 递归处理所有子节点
|
|
44
32
|
if (node._children) {
|
|
45
33
|
for (const childRef of node._children) {
|
|
46
34
|
const childEnd = getSubtreeEndIndex(data, childRef.__id__);
|
|
@@ -48,14 +36,12 @@ function getSubtreeEndIndex(data, nodeIndex) {
|
|
|
48
36
|
}
|
|
49
37
|
}
|
|
50
38
|
|
|
51
|
-
// 处理组件
|
|
52
39
|
if (node._components) {
|
|
53
40
|
for (const compRef of node._components) {
|
|
54
41
|
lastIndex = Math.max(lastIndex, compRef.__id__);
|
|
55
42
|
}
|
|
56
43
|
}
|
|
57
44
|
|
|
58
|
-
// PrefabInfo 在最后(根节点的除外,它在整个数组最后)
|
|
59
45
|
if (node._prefab && nodeIndex !== 1) {
|
|
60
46
|
lastIndex = Math.max(lastIndex, node._prefab.__id__);
|
|
61
47
|
}
|
|
@@ -66,7 +52,7 @@ function getSubtreeEndIndex(data, nodeIndex) {
|
|
|
66
52
|
/**
|
|
67
53
|
* 重建所有 __id__ 引用
|
|
68
54
|
*/
|
|
69
|
-
function
|
|
55
|
+
function rebuildReferencesForInsert(data, insertIndex, count) {
|
|
70
56
|
const indexMap = {};
|
|
71
57
|
|
|
72
58
|
for (let oldIndex = 0; oldIndex < data.length; oldIndex++) {
|
|
@@ -101,7 +87,7 @@ function rebuildReferences(data, insertIndex, count) {
|
|
|
101
87
|
|
|
102
88
|
function run(args) {
|
|
103
89
|
if (args.length < 3) {
|
|
104
|
-
|
|
90
|
+
outputError('用法: cocos2d-cli add <场景.fire | 预制体.prefab> <父节点索引> <节点名称> [选项]');
|
|
105
91
|
return;
|
|
106
92
|
}
|
|
107
93
|
|
|
@@ -109,62 +95,50 @@ function run(args) {
|
|
|
109
95
|
const parentRef = args[1];
|
|
110
96
|
const nodeName = args[2];
|
|
111
97
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
else if (key === 'at') options.at = parseInt(value);
|
|
123
|
-
else if (key === 'active') options.active = value !== 'false';
|
|
124
|
-
else if (key === 'color') options.color = value;
|
|
125
|
-
else if (key === 'fontSize') options.fontSize = parseInt(value) || 40;
|
|
126
|
-
else if (key === 'string') options.string = value || '';
|
|
127
|
-
}
|
|
128
|
-
});
|
|
98
|
+
const options = parseOptions(args, 3);
|
|
99
|
+
|
|
100
|
+
// 转换数值类型
|
|
101
|
+
if (options.x) options.x = parseFloat(options.x) || 0;
|
|
102
|
+
if (options.y) options.y = parseFloat(options.y) || 0;
|
|
103
|
+
if (options.width) options.width = parseFloat(options.width) || 0;
|
|
104
|
+
if (options.height) options.height = parseFloat(options.height) || 0;
|
|
105
|
+
if (options.at !== undefined) options.at = parseInt(options.at);
|
|
106
|
+
if (options.active !== undefined) options.active = options.active !== 'false';
|
|
107
|
+
if (options.fontSize) options.fontSize = parseInt(options.fontSize) || 40;
|
|
129
108
|
|
|
130
109
|
try {
|
|
131
110
|
const data = loadScene(filePath);
|
|
132
111
|
const { prefab } = buildMaps(data);
|
|
133
112
|
|
|
134
113
|
if (!/^\d+$/.test(parentRef)) {
|
|
135
|
-
|
|
114
|
+
outputError('父节点必须使用数字索引,请先用 tree 命令查看节点索引');
|
|
136
115
|
return;
|
|
137
116
|
}
|
|
138
117
|
|
|
139
118
|
const parentIndex = parseInt(parentRef);
|
|
140
119
|
|
|
141
120
|
if (parentIndex < 0 || parentIndex >= data.length || !data[parentIndex]) {
|
|
142
|
-
|
|
121
|
+
outputError(`无效的节点索引: ${parentRef}`);
|
|
143
122
|
return;
|
|
144
123
|
}
|
|
145
124
|
|
|
146
125
|
const parentNode = data[parentIndex];
|
|
147
126
|
const isRootChild = prefab && parentIndex === 1;
|
|
148
127
|
|
|
149
|
-
//
|
|
128
|
+
// 确定插入位置
|
|
150
129
|
let insertIndex;
|
|
151
130
|
|
|
152
131
|
if (!parentNode._children || parentNode._children.length === 0) {
|
|
153
|
-
// 父节点还没有子节点,插入到父节点之后
|
|
154
132
|
insertIndex = parentIndex + 1;
|
|
155
133
|
} else {
|
|
156
|
-
// 父节点已有子节点,根据 --at 参数确定位置
|
|
157
134
|
const targetPosition = options.at >= 0 ? options.at : parentNode._children.length;
|
|
158
135
|
|
|
159
136
|
if (targetPosition === 0) {
|
|
160
|
-
// 插入到第一个子节点之前
|
|
161
137
|
insertIndex = parentNode._children[0].__id__;
|
|
162
138
|
} else if (targetPosition >= parentNode._children.length) {
|
|
163
|
-
// 插入到最后一个子节点之后
|
|
164
139
|
const lastChildRef = parentNode._children[parentNode._children.length - 1];
|
|
165
140
|
insertIndex = getSubtreeEndIndex(data, lastChildRef.__id__) + 1;
|
|
166
141
|
} else {
|
|
167
|
-
// 插入到中间
|
|
168
142
|
insertIndex = parentNode._children[targetPosition].__id__;
|
|
169
143
|
}
|
|
170
144
|
}
|
|
@@ -173,39 +147,16 @@ function run(args) {
|
|
|
173
147
|
|
|
174
148
|
if (prefab) {
|
|
175
149
|
// 预制体模式
|
|
176
|
-
// 找到根节点的 PrefabInfo
|
|
177
150
|
const rootPrefabInfoOldIdx = getRootPrefabInfoIndex(data);
|
|
178
151
|
const rootPrefabInfo = data[rootPrefabInfoOldIdx];
|
|
179
152
|
|
|
180
153
|
// 创建节点
|
|
181
|
-
const nodeData =
|
|
182
|
-
"__type__": "cc.Node",
|
|
183
|
-
"_name": nodeName,
|
|
184
|
-
"_objFlags": 0,
|
|
185
|
-
"_parent": { "__id__": parentIndex },
|
|
186
|
-
"_children": [],
|
|
187
|
-
"_active": options.active !== false,
|
|
188
|
-
"_components": [],
|
|
189
|
-
"_prefab": null,
|
|
190
|
-
"_opacity": 255,
|
|
191
|
-
"_color": parseColor(options.color) || { "__type__": "cc.Color", "r": 255, "g": 255, "b": 255, "a": 255 },
|
|
192
|
-
"_contentSize": { "__type__": "cc.Size", "width": options.width || 0, "height": options.height || 0 },
|
|
193
|
-
"_anchorPoint": { "__type__": "cc.Vec2", "x": 0.5, "y": 0.5 },
|
|
194
|
-
"_trs": { "__type__": "TypedArray", "ctor": "Float64Array", "array": [options.x || 0, options.y || 0, 0, 0, 0, 0, 1, 1, 1, 1] },
|
|
195
|
-
"_eulerAngles": { "__type__": "cc.Vec3", "x": 0, "y": 0, "z": 0 },
|
|
196
|
-
"_skewX": 0,
|
|
197
|
-
"_skewY": 0,
|
|
198
|
-
"_is3DNode": false,
|
|
199
|
-
"_groupIndex": 0,
|
|
200
|
-
"groupIndex": 0,
|
|
201
|
-
"_id": ""
|
|
202
|
-
};
|
|
154
|
+
const nodeData = createNodeData(nodeName, parentIndex, options);
|
|
203
155
|
|
|
204
|
-
//
|
|
156
|
+
// 创建组件
|
|
205
157
|
let compData = null;
|
|
206
158
|
if (options.type) {
|
|
207
|
-
compData =
|
|
208
|
-
// 修改组件属性
|
|
159
|
+
compData = createComponent(options.type, insertIndex);
|
|
209
160
|
if (compData) {
|
|
210
161
|
if (options.type === 'label') {
|
|
211
162
|
if (options.fontSize) {
|
|
@@ -229,31 +180,25 @@ function run(args) {
|
|
|
229
180
|
"sync": false
|
|
230
181
|
};
|
|
231
182
|
|
|
232
|
-
// 构建要插入的元素:节点 → 组件 → PrefabInfo
|
|
233
183
|
const itemsToInsert = [nodeData];
|
|
234
184
|
if (compData) itemsToInsert.push(compData);
|
|
235
185
|
itemsToInsert.push(prefabInfo);
|
|
236
186
|
|
|
237
|
-
// 如果是根节点的子节点,先移除根 PrefabInfo
|
|
238
187
|
if (isRootChild) {
|
|
239
|
-
// 如果插入位置在根 PrefabInfo 之后,需要调整
|
|
240
188
|
if (insertIndex > rootPrefabInfoOldIdx) {
|
|
241
189
|
insertIndex--;
|
|
242
190
|
}
|
|
243
191
|
data.splice(rootPrefabInfoOldIdx, 1);
|
|
244
192
|
}
|
|
245
193
|
|
|
246
|
-
// 插入元素
|
|
247
194
|
for (let i = 0; i < itemsToInsert.length; i++) {
|
|
248
195
|
data.splice(insertIndex + i, 0, itemsToInsert[i]);
|
|
249
196
|
}
|
|
250
197
|
|
|
251
|
-
|
|
252
|
-
rebuildReferences(data, insertIndex, itemsToInsert.length);
|
|
198
|
+
rebuildReferencesForInsert(data, insertIndex, itemsToInsert.length);
|
|
253
199
|
|
|
254
200
|
newNodeIndex = insertIndex;
|
|
255
201
|
|
|
256
|
-
// 设置引用
|
|
257
202
|
if (compData) {
|
|
258
203
|
compData.node = { "__id__": newNodeIndex };
|
|
259
204
|
nodeData._components.push({ "__id__": newNodeIndex + 1 });
|
|
@@ -262,27 +207,20 @@ function run(args) {
|
|
|
262
207
|
nodeData._prefab = { "__id__": newNodeIndex + 1 };
|
|
263
208
|
}
|
|
264
209
|
|
|
265
|
-
// 如果是根节点的子节点,把根 PrefabInfo 添加到最后
|
|
266
210
|
if (isRootChild) {
|
|
267
211
|
data.push(rootPrefabInfo);
|
|
268
212
|
data[1]._prefab = { "__id__": data.length - 1 };
|
|
269
213
|
}
|
|
270
214
|
|
|
271
215
|
} else {
|
|
272
|
-
//
|
|
216
|
+
// 场景模式
|
|
273
217
|
const newNode = createNodeData(nodeName, parentIndex, options);
|
|
274
218
|
|
|
275
|
-
if (options.color) {
|
|
276
|
-
const color = parseColor(options.color);
|
|
277
|
-
if (color) newNode._color = color;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
219
|
const itemsToInsert = [newNode];
|
|
281
220
|
|
|
282
221
|
let compData = null;
|
|
283
222
|
if (options.type) {
|
|
284
|
-
compData =
|
|
285
|
-
// 修改组件属性
|
|
223
|
+
compData = createComponent(options.type, insertIndex);
|
|
286
224
|
if (compData) {
|
|
287
225
|
if (options.type === 'label') {
|
|
288
226
|
if (options.fontSize) {
|
|
@@ -302,7 +240,7 @@ function run(args) {
|
|
|
302
240
|
data.splice(insertIndex + i, 0, itemsToInsert[i]);
|
|
303
241
|
}
|
|
304
242
|
|
|
305
|
-
|
|
243
|
+
rebuildReferencesForInsert(data, insertIndex, itemsToInsert.length);
|
|
306
244
|
|
|
307
245
|
newNodeIndex = insertIndex;
|
|
308
246
|
|
|
@@ -317,40 +255,19 @@ function run(args) {
|
|
|
317
255
|
const insertPosition = options.at >= 0 ? options.at : parentNode._children.length;
|
|
318
256
|
parentNode._children.splice(insertPosition, 0, { "__id__": newNodeIndex });
|
|
319
257
|
|
|
320
|
-
// 保存文件
|
|
321
258
|
saveScene(filePath, data);
|
|
322
|
-
|
|
323
|
-
// 触发编辑器刷新
|
|
324
259
|
refreshEditor(filePath);
|
|
325
260
|
|
|
326
|
-
|
|
327
|
-
success: true,
|
|
261
|
+
outputSuccess({
|
|
328
262
|
nodeIndex: newNodeIndex,
|
|
329
263
|
name: nodeName,
|
|
330
264
|
parent: parentRef,
|
|
331
265
|
type: prefab ? 'prefab' : 'scene'
|
|
332
|
-
})
|
|
266
|
+
});
|
|
333
267
|
|
|
334
268
|
} catch (err) {
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function parseColor(colorStr) {
|
|
340
|
-
if (!colorStr) return null;
|
|
341
|
-
let color = colorStr;
|
|
342
|
-
if (typeof color === 'string') {
|
|
343
|
-
if (color.startsWith('#')) color = color.slice(1);
|
|
344
|
-
if (color.length === 6) {
|
|
345
|
-
const r = parseInt(color.slice(0, 2), 16);
|
|
346
|
-
const g = parseInt(color.slice(2, 4), 16);
|
|
347
|
-
const b = parseInt(color.slice(4, 6), 16);
|
|
348
|
-
if (!isNaN(r) && !isNaN(g) && !isNaN(b)) {
|
|
349
|
-
return { "__type__": "cc.Color", r, g, b, a: 255 };
|
|
350
|
-
}
|
|
351
|
-
}
|
|
269
|
+
outputError(err.message);
|
|
352
270
|
}
|
|
353
|
-
return null;
|
|
354
271
|
}
|
|
355
272
|
|
|
356
273
|
module.exports = { run };
|
package/src/commands/build.js
CHANGED