@akiojin/unity-mcp-server 2.14.14
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/LICENSE +21 -0
- package/README.md +206 -0
- package/bin/unity-mcp-server +2 -0
- package/package.json +73 -0
- package/src/core/codeIndex.js +163 -0
- package/src/core/codeIndexDb.js +96 -0
- package/src/core/config.js +165 -0
- package/src/core/indexWatcher.js +52 -0
- package/src/core/projectInfo.js +111 -0
- package/src/core/server.js +294 -0
- package/src/core/unityConnection.js +426 -0
- package/src/handlers/analysis/AnalyzeSceneContentsToolHandler.js +35 -0
- package/src/handlers/analysis/FindByComponentToolHandler.js +20 -0
- package/src/handlers/analysis/GetAnimatorStateToolHandler.js +37 -0
- package/src/handlers/analysis/GetComponentValuesToolHandler.js +20 -0
- package/src/handlers/analysis/GetGameObjectDetailsToolHandler.js +35 -0
- package/src/handlers/analysis/GetInputActionsStateToolHandler.js +37 -0
- package/src/handlers/analysis/GetObjectReferencesToolHandler.js +20 -0
- package/src/handlers/asset/AssetDatabaseToolHandler.js +221 -0
- package/src/handlers/asset/AssetDependencyToolHandler.js +201 -0
- package/src/handlers/asset/AssetImportSettingsToolHandler.js +170 -0
- package/src/handlers/asset/CreateMaterialToolHandler.js +96 -0
- package/src/handlers/asset/CreatePrefabToolHandler.js +78 -0
- package/src/handlers/asset/ExitPrefabModeToolHandler.js +83 -0
- package/src/handlers/asset/InstantiatePrefabToolHandler.js +133 -0
- package/src/handlers/asset/ModifyMaterialToolHandler.js +76 -0
- package/src/handlers/asset/ModifyPrefabToolHandler.js +72 -0
- package/src/handlers/asset/OpenPrefabToolHandler.js +121 -0
- package/src/handlers/asset/SavePrefabToolHandler.js +106 -0
- package/src/handlers/base/BaseToolHandler.js +133 -0
- package/src/handlers/compilation/GetCompilationStateToolHandler.js +90 -0
- package/src/handlers/component/AddComponentToolHandler.js +126 -0
- package/src/handlers/component/GetComponentTypesToolHandler.js +100 -0
- package/src/handlers/component/ListComponentsToolHandler.js +85 -0
- package/src/handlers/component/ModifyComponentToolHandler.js +143 -0
- package/src/handlers/component/RemoveComponentToolHandler.js +108 -0
- package/src/handlers/console/ClearConsoleToolHandler.js +160 -0
- package/src/handlers/console/ReadConsoleToolHandler.js +276 -0
- package/src/handlers/editor/LayerManagementToolHandler.js +160 -0
- package/src/handlers/editor/SelectionToolHandler.js +141 -0
- package/src/handlers/editor/TagManagementToolHandler.js +129 -0
- package/src/handlers/editor/ToolManagementToolHandler.js +135 -0
- package/src/handlers/editor/WindowManagementToolHandler.js +125 -0
- package/src/handlers/gameobject/CreateGameObjectToolHandler.js +131 -0
- package/src/handlers/gameobject/DeleteGameObjectToolHandler.js +101 -0
- package/src/handlers/gameobject/FindGameObjectToolHandler.js +119 -0
- package/src/handlers/gameobject/GetHierarchyToolHandler.js +132 -0
- package/src/handlers/gameobject/ModifyGameObjectToolHandler.js +128 -0
- package/src/handlers/index.js +389 -0
- package/src/handlers/input/AddInputActionToolHandler.js +20 -0
- package/src/handlers/input/AddInputBindingToolHandler.js +20 -0
- package/src/handlers/input/CreateActionMapToolHandler.js +20 -0
- package/src/handlers/input/CreateCompositeBindingToolHandler.js +20 -0
- package/src/handlers/input/GamepadSimulationHandler.js +116 -0
- package/src/handlers/input/InputSystemHandler.js +80 -0
- package/src/handlers/input/KeyboardSimulationHandler.js +79 -0
- package/src/handlers/input/ManageControlSchemesToolHandler.js +20 -0
- package/src/handlers/input/MouseSimulationHandler.js +107 -0
- package/src/handlers/input/RemoveActionMapToolHandler.js +20 -0
- package/src/handlers/input/RemoveAllBindingsToolHandler.js +20 -0
- package/src/handlers/input/RemoveInputActionToolHandler.js +20 -0
- package/src/handlers/input/RemoveInputBindingToolHandler.js +20 -0
- package/src/handlers/input/TouchSimulationHandler.js +142 -0
- package/src/handlers/menu/ExecuteMenuItemToolHandler.js +304 -0
- package/src/handlers/package/PackageManagerToolHandler.js +248 -0
- package/src/handlers/package/RegistryConfigToolHandler.js +198 -0
- package/src/handlers/playmode/GetEditorStateToolHandler.js +81 -0
- package/src/handlers/playmode/PauseToolHandler.js +44 -0
- package/src/handlers/playmode/PlayToolHandler.js +91 -0
- package/src/handlers/playmode/StopToolHandler.js +77 -0
- package/src/handlers/playmode/WaitForEditorStateToolHandler.js +45 -0
- package/src/handlers/scene/CreateSceneToolHandler.js +91 -0
- package/src/handlers/scene/GetSceneInfoToolHandler.js +20 -0
- package/src/handlers/scene/ListScenesToolHandler.js +58 -0
- package/src/handlers/scene/LoadSceneToolHandler.js +92 -0
- package/src/handlers/scene/SaveSceneToolHandler.js +76 -0
- package/src/handlers/screenshot/AnalyzeScreenshotToolHandler.js +238 -0
- package/src/handlers/screenshot/CaptureScreenshotToolHandler.js +692 -0
- package/src/handlers/script/BuildCodeIndexToolHandler.js +163 -0
- package/src/handlers/script/ScriptCreateClassFileToolHandler.js +60 -0
- package/src/handlers/script/ScriptEditStructuredToolHandler.js +173 -0
- package/src/handlers/script/ScriptIndexStatusToolHandler.js +61 -0
- package/src/handlers/script/ScriptPackagesListToolHandler.js +103 -0
- package/src/handlers/script/ScriptReadToolHandler.js +106 -0
- package/src/handlers/script/ScriptRefactorRenameToolHandler.js +83 -0
- package/src/handlers/script/ScriptRefsFindToolHandler.js +144 -0
- package/src/handlers/script/ScriptRemoveSymbolToolHandler.js +79 -0
- package/src/handlers/script/ScriptSearchToolHandler.js +320 -0
- package/src/handlers/script/ScriptSymbolFindToolHandler.js +117 -0
- package/src/handlers/script/ScriptSymbolsGetToolHandler.js +96 -0
- package/src/handlers/settings/GetProjectSettingsToolHandler.js +161 -0
- package/src/handlers/settings/UpdateProjectSettingsToolHandler.js +272 -0
- package/src/handlers/system/GetCommandStatsToolHandler.js +25 -0
- package/src/handlers/system/PingToolHandler.js +53 -0
- package/src/handlers/system/RefreshAssetsToolHandler.js +45 -0
- package/src/handlers/ui/ClickUIElementToolHandler.js +110 -0
- package/src/handlers/ui/FindUIElementsToolHandler.js +63 -0
- package/src/handlers/ui/GetUIElementStateToolHandler.js +50 -0
- package/src/handlers/ui/SetUIElementValueToolHandler.js +49 -0
- package/src/handlers/ui/SimulateUIInputToolHandler.js +156 -0
- package/src/handlers/video/CaptureVideoForToolHandler.js +96 -0
- package/src/handlers/video/CaptureVideoStartToolHandler.js +38 -0
- package/src/handlers/video/CaptureVideoStatusToolHandler.js +30 -0
- package/src/handlers/video/CaptureVideoStopToolHandler.js +32 -0
- package/src/lsp/CSharpLspUtils.js +134 -0
- package/src/lsp/LspProcessManager.js +60 -0
- package/src/lsp/LspRpcClient.js +133 -0
- package/src/tools/analysis/analyzeSceneContents.js +100 -0
- package/src/tools/analysis/findByComponent.js +87 -0
- package/src/tools/analysis/getAnimatorState.js +326 -0
- package/src/tools/analysis/getComponentValues.js +182 -0
- package/src/tools/analysis/getGameObjectDetails.js +159 -0
- package/src/tools/analysis/getInputActionsState.js +329 -0
- package/src/tools/analysis/getObjectReferences.js +86 -0
- package/src/tools/input/inputActionsEditor.js +556 -0
- package/src/tools/scene/createScene.js +112 -0
- package/src/tools/scene/getSceneInfo.js +95 -0
- package/src/tools/scene/listScenes.js +82 -0
- package/src/tools/scene/loadScene.js +122 -0
- package/src/tools/scene/saveScene.js +91 -0
- package/src/tools/system/ping.js +72 -0
- package/src/tools/video/recordFor.js +31 -0
- package/src/tools/video/recordPlayMode.js +61 -0
- package/src/utils/csharpParse.js +88 -0
- package/src/utils/validators.js +90 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Handler for the delete_gameobject tool
|
|
5
|
+
* Deletes GameObjects from the Unity scene
|
|
6
|
+
*/
|
|
7
|
+
export class DeleteGameObjectToolHandler extends BaseToolHandler {
|
|
8
|
+
constructor(unityConnection) {
|
|
9
|
+
super(
|
|
10
|
+
'delete_gameobject',
|
|
11
|
+
'Delete GameObject(s) by path or paths (optionally include children).',
|
|
12
|
+
{
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
path: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'Path to a single GameObject to delete'
|
|
18
|
+
},
|
|
19
|
+
paths: {
|
|
20
|
+
type: 'array',
|
|
21
|
+
description: 'Array of paths to multiple GameObjects to delete',
|
|
22
|
+
items: {
|
|
23
|
+
type: 'string'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
includeChildren: {
|
|
27
|
+
type: 'boolean',
|
|
28
|
+
description: 'Whether to delete children (default: true)'
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
required: []
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
this.unityConnection = unityConnection;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Validates the input parameters
|
|
40
|
+
* @param {object} params - Input parameters
|
|
41
|
+
* @throws {Error} If validation fails
|
|
42
|
+
*/
|
|
43
|
+
validate(params) {
|
|
44
|
+
super.validate(params);
|
|
45
|
+
|
|
46
|
+
// Either path or paths must be provided
|
|
47
|
+
if (!params.path && (!params.paths || params.paths.length === 0)) {
|
|
48
|
+
throw new Error('Either "path" or "paths" parameter must be provided');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Validate paths array if provided
|
|
52
|
+
if (params.paths) {
|
|
53
|
+
if (!Array.isArray(params.paths)) {
|
|
54
|
+
throw new Error('paths must be an array of strings');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (const path of params.paths) {
|
|
58
|
+
if (typeof path !== 'string') {
|
|
59
|
+
throw new Error('All paths must be strings');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Executes the delete_gameobject command
|
|
67
|
+
* @param {object} params - Input parameters
|
|
68
|
+
* @returns {Promise<object>} Deletion result
|
|
69
|
+
*/
|
|
70
|
+
async execute(params) {
|
|
71
|
+
// Ensure connected
|
|
72
|
+
if (!this.unityConnection.isConnected()) {
|
|
73
|
+
await this.unityConnection.connect();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Send delete_gameobject command
|
|
77
|
+
const result = await this.unityConnection.sendCommand('delete_gameobject', params);
|
|
78
|
+
|
|
79
|
+
// Check for errors from Unity
|
|
80
|
+
if (result.error) {
|
|
81
|
+
throw new Error(result.error);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Add summary
|
|
85
|
+
if (result.deletedCount !== undefined) {
|
|
86
|
+
if (result.deletedCount === 0) {
|
|
87
|
+
result.summary = 'No GameObjects were deleted';
|
|
88
|
+
} else if (result.deletedCount === 1) {
|
|
89
|
+
result.summary = `Deleted 1 GameObject: ${result.deleted[0]}`;
|
|
90
|
+
} else {
|
|
91
|
+
result.summary = `Deleted ${result.deletedCount} GameObjects`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (result.notFoundCount > 0) {
|
|
95
|
+
result.summary += ` (${result.notFoundCount} not found)`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Handler for the find_gameobject tool
|
|
5
|
+
* Finds GameObjects in Unity scene by various criteria
|
|
6
|
+
*/
|
|
7
|
+
export class FindGameObjectToolHandler extends BaseToolHandler {
|
|
8
|
+
constructor(unityConnection) {
|
|
9
|
+
super(
|
|
10
|
+
'find_gameobject',
|
|
11
|
+
'Find GameObjects by name, tag, or layer with optional exact matching.',
|
|
12
|
+
{
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
name: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'Name to search for'
|
|
18
|
+
},
|
|
19
|
+
tag: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
description: 'Tag to search for'
|
|
22
|
+
},
|
|
23
|
+
layer: {
|
|
24
|
+
type: 'number',
|
|
25
|
+
description: 'Layer index to search for (0-31)',
|
|
26
|
+
minimum: 0,
|
|
27
|
+
maximum: 31
|
|
28
|
+
},
|
|
29
|
+
exactMatch: {
|
|
30
|
+
type: 'boolean',
|
|
31
|
+
description: 'Whether to match name exactly (default: false)'
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
required: []
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
this.unityConnection = unityConnection;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Validates the input parameters
|
|
43
|
+
* @param {object} params - Input parameters
|
|
44
|
+
* @throws {Error} If validation fails
|
|
45
|
+
*/
|
|
46
|
+
validate(params) {
|
|
47
|
+
super.validate(params);
|
|
48
|
+
|
|
49
|
+
// At least one search criteria must be provided
|
|
50
|
+
if (!params.name && !params.tag && params.layer === undefined) {
|
|
51
|
+
throw new Error('At least one search criteria (name, tag, or layer) must be provided');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Validate layer
|
|
55
|
+
if (params.layer !== undefined) {
|
|
56
|
+
const layer = Number(params.layer);
|
|
57
|
+
if (isNaN(layer) || layer < 0 || layer > 31) {
|
|
58
|
+
throw new Error('layer must be a number between 0 and 31');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Executes the find_gameobject command
|
|
65
|
+
* @param {object} params - Input parameters
|
|
66
|
+
* @returns {Promise<object>} Found GameObjects
|
|
67
|
+
*/
|
|
68
|
+
async execute(params) {
|
|
69
|
+
// Ensure connected
|
|
70
|
+
if (!this.unityConnection.isConnected()) {
|
|
71
|
+
await this.unityConnection.connect();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Send find_gameobject command
|
|
75
|
+
const result = await this.unityConnection.sendCommand('find_gameobject', params);
|
|
76
|
+
|
|
77
|
+
// Check for errors from Unity
|
|
78
|
+
if (result.error) {
|
|
79
|
+
throw new Error(result.error);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Add summary information
|
|
83
|
+
if (result.objects && Array.isArray(result.objects)) {
|
|
84
|
+
result.summary = this.generateSummary(result.objects, params);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Generates a summary of the search results
|
|
92
|
+
* @param {Array} objects - Found GameObjects
|
|
93
|
+
* @param {object} searchParams - Search parameters used
|
|
94
|
+
* @returns {string} Summary text
|
|
95
|
+
*/
|
|
96
|
+
generateSummary(objects, searchParams) {
|
|
97
|
+
const parts = [];
|
|
98
|
+
|
|
99
|
+
if (searchParams.name) {
|
|
100
|
+
parts.push(`name${searchParams.exactMatch === false ? ' containing' : ''} "${searchParams.name}"`);
|
|
101
|
+
}
|
|
102
|
+
if (searchParams.tag) {
|
|
103
|
+
parts.push(`tag "${searchParams.tag}"`);
|
|
104
|
+
}
|
|
105
|
+
if (searchParams.layer !== undefined) {
|
|
106
|
+
parts.push(`layer ${searchParams.layer}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const criteria = parts.join(', ');
|
|
110
|
+
|
|
111
|
+
if (objects.length === 0) {
|
|
112
|
+
return `No GameObjects found matching ${criteria}`;
|
|
113
|
+
} else if (objects.length === 1) {
|
|
114
|
+
return `Found 1 GameObject matching ${criteria}: ${objects[0].name}`;
|
|
115
|
+
} else {
|
|
116
|
+
return `Found ${objects.length} GameObjects matching ${criteria}`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Handler for the get_hierarchy tool
|
|
5
|
+
* Gets the Unity scene hierarchy
|
|
6
|
+
*/
|
|
7
|
+
export class GetHierarchyToolHandler extends BaseToolHandler {
|
|
8
|
+
constructor(unityConnection) {
|
|
9
|
+
super(
|
|
10
|
+
'get_hierarchy',
|
|
11
|
+
'Get scene hierarchy. For large scenes, prefer nameOnly=true. With nameOnly, use maxObjects ~100–500; when requesting details, keep maxObjects ~10–50 to conserve tokens. Only enable includeComponents/includeTransform when necessary.',
|
|
12
|
+
{
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
rootPath: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description: 'Path to GameObject whose children will be the root of the returned hierarchy (e.g., "/Team_0" returns Team_0\'s children). If not specified, returns scene root objects.'
|
|
18
|
+
},
|
|
19
|
+
includeInactive: {
|
|
20
|
+
type: 'boolean',
|
|
21
|
+
description: 'Include inactive GameObjects (default: true)'
|
|
22
|
+
},
|
|
23
|
+
maxDepth: {
|
|
24
|
+
type: 'number',
|
|
25
|
+
description: 'Maximum depth to traverse from the root. 0=immediate children only (default), 1=children+grandchildren, 2=children+grandchildren+great-grandchildren, etc. (-1 for unlimited)',
|
|
26
|
+
minimum: -1
|
|
27
|
+
},
|
|
28
|
+
includeComponents: {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
description: 'Include component information (default: false). WARNING: Significantly increases response size - use with small maxObjects values.'
|
|
31
|
+
},
|
|
32
|
+
includeTransform: {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
description: 'Include transform information (default: false). WARNING: Increases response size - use with small maxObjects values.'
|
|
35
|
+
},
|
|
36
|
+
includeTags: {
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
description: 'Include tag information (default: false)'
|
|
39
|
+
},
|
|
40
|
+
includeLayers: {
|
|
41
|
+
type: 'boolean',
|
|
42
|
+
description: 'Include layer information (default: false)'
|
|
43
|
+
},
|
|
44
|
+
nameOnly: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
description: 'Return only names and paths for minimal data size (default: false). RECOMMENDED for large hierarchies to reduce token usage.'
|
|
47
|
+
},
|
|
48
|
+
maxObjects: {
|
|
49
|
+
type: 'number',
|
|
50
|
+
description: 'Maximum number of objects to include in response. Unity default: 100 (-1 for unlimited). RECOMMENDED: 10-50 for detailed info, 100-500 for nameOnly mode to avoid MCP token limits',
|
|
51
|
+
minimum: -1
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
required: []
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
this.unityConnection = unityConnection;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Validates the input parameters
|
|
63
|
+
* @param {object} params - Input parameters
|
|
64
|
+
* @throws {Error} If validation fails
|
|
65
|
+
*/
|
|
66
|
+
validate(params) {
|
|
67
|
+
super.validate(params);
|
|
68
|
+
|
|
69
|
+
// Validate maxDepth
|
|
70
|
+
if (params.maxDepth !== undefined) {
|
|
71
|
+
const depth = Number(params.maxDepth);
|
|
72
|
+
if (isNaN(depth) || depth < -1) {
|
|
73
|
+
throw new Error('maxDepth must be -1 or a positive number');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Validate maxObjects
|
|
78
|
+
if (params.maxObjects !== undefined) {
|
|
79
|
+
const maxObjects = Number(params.maxObjects);
|
|
80
|
+
if (isNaN(maxObjects) || maxObjects < -1) {
|
|
81
|
+
throw new Error('maxObjects must be -1 or a positive number');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Executes the get_hierarchy command
|
|
88
|
+
* @param {object} params - Input parameters
|
|
89
|
+
* @returns {Promise<object>} Scene hierarchy
|
|
90
|
+
*/
|
|
91
|
+
async execute(params) {
|
|
92
|
+
// Ensure connected
|
|
93
|
+
if (!this.unityConnection.isConnected()) {
|
|
94
|
+
await this.unityConnection.connect();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Send get_hierarchy command
|
|
98
|
+
const result = await this.unityConnection.sendCommand('get_hierarchy', params);
|
|
99
|
+
|
|
100
|
+
// Check for errors from Unity
|
|
101
|
+
if (result.error) {
|
|
102
|
+
throw new Error(result.error);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Add helpful summary
|
|
106
|
+
if (result.hierarchy) {
|
|
107
|
+
result.totalObjects = this.countObjects(result.hierarchy);
|
|
108
|
+
result.summary = `Scene "${result.sceneName}" contains ${result.totalObjects} GameObject${result.totalObjects !== 1 ? 's' : ''} (${result.objectCount} at root level)`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Counts total objects in hierarchy recursively
|
|
116
|
+
* @param {Array} hierarchy - Hierarchy array
|
|
117
|
+
* @returns {number} Total object count
|
|
118
|
+
*/
|
|
119
|
+
countObjects(hierarchy) {
|
|
120
|
+
let count = 0;
|
|
121
|
+
|
|
122
|
+
for (const node of hierarchy) {
|
|
123
|
+
count++; // Count this node
|
|
124
|
+
|
|
125
|
+
if (node.children && Array.isArray(node.children)) {
|
|
126
|
+
count += this.countObjects(node.children);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return count;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
2
|
+
import { validateVector3, validateLayer, validateGameObjectPath } from '../../utils/validators.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Handler for the modify_gameobject tool
|
|
6
|
+
* Modifies properties of existing GameObjects
|
|
7
|
+
*/
|
|
8
|
+
export class ModifyGameObjectToolHandler extends BaseToolHandler {
|
|
9
|
+
constructor(unityConnection) {
|
|
10
|
+
super(
|
|
11
|
+
'modify_gameobject',
|
|
12
|
+
'Modify GameObject properties (transform/name/parent/active/tag/layer).',
|
|
13
|
+
{
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {
|
|
16
|
+
path: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
description: 'Path to the GameObject to modify (required)'
|
|
19
|
+
},
|
|
20
|
+
name: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
description: 'New name for the GameObject'
|
|
23
|
+
},
|
|
24
|
+
position: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
description: 'New world position',
|
|
27
|
+
properties: {
|
|
28
|
+
x: { type: 'number' },
|
|
29
|
+
y: { type: 'number' },
|
|
30
|
+
z: { type: 'number' }
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
rotation: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
description: 'New rotation in Euler angles',
|
|
36
|
+
properties: {
|
|
37
|
+
x: { type: 'number' },
|
|
38
|
+
y: { type: 'number' },
|
|
39
|
+
z: { type: 'number' }
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
scale: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
description: 'New local scale',
|
|
45
|
+
properties: {
|
|
46
|
+
x: { type: 'number' },
|
|
47
|
+
y: { type: 'number' },
|
|
48
|
+
z: { type: 'number' }
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
active: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
description: 'Set active state'
|
|
54
|
+
},
|
|
55
|
+
parentPath: {
|
|
56
|
+
type: ['string', 'null'],
|
|
57
|
+
description: 'Path to new parent GameObject (null to unparent)'
|
|
58
|
+
},
|
|
59
|
+
tag: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
description: 'New tag'
|
|
62
|
+
},
|
|
63
|
+
layer: {
|
|
64
|
+
type: 'number',
|
|
65
|
+
description: 'New layer index (0-31)',
|
|
66
|
+
minimum: 0,
|
|
67
|
+
maximum: 31
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
required: ['path']
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
this.unityConnection = unityConnection;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Validates the input parameters
|
|
79
|
+
* @param {object} params - Input parameters
|
|
80
|
+
* @throws {Error} If validation fails
|
|
81
|
+
*/
|
|
82
|
+
validate(params) {
|
|
83
|
+
super.validate(params);
|
|
84
|
+
|
|
85
|
+
// Path is required
|
|
86
|
+
validateGameObjectPath(params.path);
|
|
87
|
+
|
|
88
|
+
// At least one modification must be specified
|
|
89
|
+
const modifiableProps = ['name', 'position', 'rotation', 'scale', 'active', 'parentPath', 'tag', 'layer'];
|
|
90
|
+
const hasModification = modifiableProps.some(prop => params.hasOwnProperty(prop));
|
|
91
|
+
|
|
92
|
+
if (!hasModification) {
|
|
93
|
+
throw new Error('At least one property to modify must be specified');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Validate vector3 properties
|
|
97
|
+
if (params.position) validateVector3(params.position, 'position');
|
|
98
|
+
if (params.rotation) validateVector3(params.rotation, 'rotation');
|
|
99
|
+
if (params.scale) validateVector3(params.scale, 'scale');
|
|
100
|
+
|
|
101
|
+
// Validate layer
|
|
102
|
+
if (params.layer !== undefined) {
|
|
103
|
+
validateLayer(Number(params.layer));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Executes the modify_gameobject command
|
|
109
|
+
* @param {object} params - Input parameters
|
|
110
|
+
* @returns {Promise<object>} Modified GameObject info
|
|
111
|
+
*/
|
|
112
|
+
async execute(params) {
|
|
113
|
+
// Ensure connected
|
|
114
|
+
if (!this.unityConnection.isConnected()) {
|
|
115
|
+
await this.unityConnection.connect();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Send modify_gameobject command
|
|
119
|
+
const result = await this.unityConnection.sendCommand('modify_gameobject', params);
|
|
120
|
+
|
|
121
|
+
// Check for errors from Unity
|
|
122
|
+
if (result.error) {
|
|
123
|
+
throw new Error(result.error);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
}
|