@akiojin/unity-mcp-server 2.40.2 → 2.40.3
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/README.md +21 -0
- package/bin/unity-mcp-server +1 -1
- package/package.json +1 -1
- package/src/core/codeIndex.js +64 -15
- package/src/core/server.js +3 -34
- package/src/handlers/analysis/AnalyzeSceneContentsToolHandler.js +27 -24
- package/src/handlers/analysis/FindByComponentToolHandler.js +4 -1
- package/src/handlers/analysis/GetAnimatorStateToolHandler.js +5 -5
- package/src/handlers/analysis/GetComponentValuesToolHandler.js +4 -1
- package/src/handlers/analysis/GetGameObjectDetailsToolHandler.js +27 -24
- package/src/handlers/analysis/GetInputActionsStateToolHandler.js +5 -5
- package/src/handlers/analysis/GetObjectReferencesToolHandler.js +4 -1
- package/src/handlers/asset/AssetDatabaseManageToolHandler.js +24 -6
- package/src/handlers/asset/AssetDependencyAnalyzeToolHandler.js +21 -11
- package/src/handlers/asset/AssetImportSettingsManageToolHandler.js +7 -7
- package/src/handlers/asset/AssetMaterialCreateToolHandler.js +78 -81
- package/src/handlers/asset/AssetMaterialModifyToolHandler.js +57 -61
- package/src/handlers/asset/AssetPrefabCreateToolHandler.js +61 -64
- package/src/handlers/asset/AssetPrefabExitModeToolHandler.js +9 -13
- package/src/handlers/asset/AssetPrefabInstantiateToolHandler.js +110 -116
- package/src/handlers/asset/AssetPrefabModifyToolHandler.js +58 -58
- package/src/handlers/asset/AssetPrefabOpenToolHandler.js +7 -5
- package/src/handlers/asset/AssetPrefabSaveToolHandler.js +13 -6
- package/src/handlers/compilation/CompilationGetStateToolHandler.js +4 -3
- package/src/handlers/component/ComponentAddToolHandler.js +2 -2
- package/src/handlers/component/ComponentGetTypesToolHandler.js +17 -21
- package/src/handlers/component/ComponentListToolHandler.js +5 -3
- package/src/handlers/component/ComponentModifyToolHandler.js +3 -3
- package/src/handlers/component/ComponentRemoveToolHandler.js +2 -2
- package/src/handlers/console/ConsoleClearToolHandler.js +36 -46
- package/src/handlers/editor/EditorLayersManageToolHandler.js +7 -6
- package/src/handlers/editor/EditorTagsManageToolHandler.js +20 -11
- package/src/handlers/editor/EditorToolsManageToolHandler.js +2 -2
- package/src/handlers/editor/EditorWindowsManageToolHandler.js +6 -5
- package/src/handlers/gameobject/GameObjectCreateToolHandler.js +62 -66
- package/src/handlers/gameobject/GameObjectDeleteToolHandler.js +9 -9
- package/src/handlers/gameobject/GameObjectFindToolHandler.js +13 -11
- package/src/handlers/gameobject/GameObjectGetHierarchyToolHandler.js +22 -16
- package/src/handlers/input/InputActionAddToolHandler.js +2 -2
- package/src/handlers/input/InputActionMapCreateToolHandler.js +2 -2
- package/src/handlers/input/InputActionMapRemoveToolHandler.js +2 -2
- package/src/handlers/input/InputActionRemoveToolHandler.js +2 -2
- package/src/handlers/input/InputBindingAddToolHandler.js +2 -2
- package/src/handlers/input/InputBindingCompositeCreateToolHandler.js +2 -2
- package/src/handlers/input/InputBindingRemoveAllToolHandler.js +2 -2
- package/src/handlers/input/InputBindingRemoveToolHandler.js +2 -2
- package/src/handlers/input/InputControlSchemesManageToolHandler.js +2 -2
- package/src/handlers/package/PackageManagerToolHandler.js +41 -44
- package/src/handlers/package/RegistryConfigToolHandler.js +28 -7
- package/src/handlers/playmode/PlaymodeGetStateToolHandler.js +12 -16
- package/src/handlers/playmode/PlaymodePauseToolHandler.js +8 -12
- package/src/handlers/playmode/PlaymodeWaitForStateToolHandler.js +6 -3
- package/src/handlers/scene/GetSceneInfoToolHandler.js +11 -11
- package/src/handlers/scene/SceneCreateToolHandler.js +28 -31
- package/src/handlers/scene/SceneListToolHandler.js +21 -24
- package/src/handlers/scene/SceneLoadToolHandler.js +27 -29
- package/src/handlers/scene/SceneSaveToolHandler.js +19 -22
- package/src/handlers/screenshot/ScreenshotCaptureToolHandler.js +88 -66
- package/src/handlers/script/CodeIndexStatusToolHandler.js +4 -3
- package/src/handlers/script/CodeIndexUpdateToolHandler.js +24 -14
- package/src/handlers/script/ScriptCreateClassToolHandler.js +44 -9
- package/src/handlers/script/ScriptPackagesListToolHandler.js +91 -91
- package/src/handlers/script/ScriptRefactorRenameToolHandler.js +80 -71
- package/src/handlers/script/ScriptRemoveSymbolToolHandler.js +21 -7
- package/src/handlers/script/ScriptSearchToolHandler.js +299 -266
- package/src/handlers/script/ScriptSymbolsGetToolHandler.js +88 -79
- package/src/handlers/settings/SettingsGetToolHandler.js +28 -13
- package/src/handlers/settings/SettingsUpdateToolHandler.js +20 -6
- package/src/handlers/ui/UIClickElementToolHandler.js +87 -96
- package/src/handlers/ui/UIFindElementsToolHandler.js +45 -55
- package/src/handlers/ui/UIGetElementStateToolHandler.js +35 -43
- package/src/handlers/ui/UISetElementValueToolHandler.js +42 -49
- package/src/handlers/ui/UISimulateInputToolHandler.js +134 -136
- package/src/handlers/video/VideoCaptureForToolHandler.js +24 -7
- package/src/lsp/LspRpcClient.js +24 -12
- package/src/tools/analysis/analyzeSceneContents.js +85 -85
- package/src/tools/analysis/findByComponent.js +73 -73
- package/src/tools/analysis/getAnimatorState.js +287 -287
- package/src/tools/analysis/getComponentValues.js +161 -161
- package/src/tools/analysis/getGameObjectDetails.js +138 -138
- package/src/tools/analysis/getInputActionsState.js +291 -291
- package/src/tools/analysis/getObjectReferences.js +72 -72
- package/src/tools/input/inputActionsEditor.js +522 -474
- package/src/tools/scene/createScene.js +98 -97
- package/src/tools/scene/getSceneInfo.js +82 -81
- package/src/tools/scene/listScenes.js +70 -69
- package/src/tools/scene/loadScene.js +108 -106
- package/src/tools/scene/saveScene.js +78 -77
- package/src/tools/system/ping.js +9 -12
- package/src/utils/validators.js +2 -2
|
@@ -5,28 +5,25 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export class SceneListToolHandler extends BaseToolHandler {
|
|
7
7
|
constructor(unityConnection) {
|
|
8
|
-
super(
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
includeLoadedOnly: {
|
|
15
|
-
type: 'boolean',
|
|
16
|
-
description: 'Only include currently loaded scenes (default: false)'
|
|
17
|
-
},
|
|
18
|
-
includeBuildScenesOnly: {
|
|
19
|
-
type: 'boolean',
|
|
20
|
-
description: 'Only include scenes in build settings (default: false)'
|
|
21
|
-
},
|
|
22
|
-
includePath: {
|
|
23
|
-
type: 'string',
|
|
24
|
-
description: 'Filter scenes by path pattern (e.g., "Levels" to find scenes in Levels folder)'
|
|
25
|
-
}
|
|
8
|
+
super('scene_list', 'List scenes in project (filter to loaded/build scenes or by path).', {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
includeLoadedOnly: {
|
|
12
|
+
type: 'boolean',
|
|
13
|
+
description: 'Only include currently loaded scenes (default: false)'
|
|
26
14
|
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
includeBuildScenesOnly: {
|
|
16
|
+
type: 'boolean',
|
|
17
|
+
description: 'Only include scenes in build settings (default: false)'
|
|
18
|
+
},
|
|
19
|
+
includePath: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
description:
|
|
22
|
+
'Filter scenes by path pattern (e.g., "Levels" to find scenes in Levels folder)'
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
required: []
|
|
26
|
+
});
|
|
30
27
|
this.unityConnection = unityConnection;
|
|
31
28
|
}
|
|
32
29
|
|
|
@@ -40,10 +37,10 @@ export class SceneListToolHandler extends BaseToolHandler {
|
|
|
40
37
|
if (!this.unityConnection.isConnected()) {
|
|
41
38
|
throw new Error('Unity connection not available');
|
|
42
39
|
}
|
|
43
|
-
|
|
40
|
+
|
|
44
41
|
// Send command to Unity
|
|
45
42
|
const result = await this.unityConnection.sendCommand('list_scenes', params);
|
|
46
|
-
|
|
43
|
+
|
|
47
44
|
// The unityConnection.sendCommand already extracts the result field
|
|
48
45
|
// Check for Unity-side errors
|
|
49
46
|
if (result && result.error) {
|
|
@@ -51,7 +48,7 @@ export class SceneListToolHandler extends BaseToolHandler {
|
|
|
51
48
|
error.code = 'UNITY_ERROR';
|
|
52
49
|
throw error;
|
|
53
50
|
}
|
|
54
|
-
|
|
51
|
+
|
|
55
52
|
// Return the result directly since it's already unwrapped
|
|
56
53
|
return result;
|
|
57
54
|
}
|
|
@@ -5,29 +5,27 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export class SceneLoadToolHandler extends BaseToolHandler {
|
|
7
7
|
constructor(unityConnection) {
|
|
8
|
-
super(
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
scenePath: {
|
|
15
|
-
type: 'string',
|
|
16
|
-
description: 'Full path to the scene file (e.g., "Assets/Scenes/MainMenu.unity")'
|
|
17
|
-
},
|
|
18
|
-
sceneName: {
|
|
19
|
-
type: 'string',
|
|
20
|
-
description: 'Name of the scene to load (must be in build settings). Use either scenePath or sceneName, not both.'
|
|
21
|
-
},
|
|
22
|
-
loadMode: {
|
|
23
|
-
type: 'string',
|
|
24
|
-
enum: ['Single', 'Additive'],
|
|
25
|
-
description: 'How to load the scene. Single replaces current scene(s), Additive adds to current scene(s) (default: Single)'
|
|
26
|
-
}
|
|
8
|
+
super('scene_load', 'Load a scene by path or name (Single/Additive).', {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
scenePath: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
description: 'Full path to the scene file (e.g., "Assets/Scenes/MainMenu.unity")'
|
|
27
14
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
sceneName: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
description:
|
|
18
|
+
'Name of the scene to load (must be in build settings). Use either scenePath or sceneName, not both.'
|
|
19
|
+
},
|
|
20
|
+
loadMode: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
enum: ['Single', 'Additive'],
|
|
23
|
+
description:
|
|
24
|
+
'How to load the scene. Single replaces current scene(s), Additive adds to current scene(s) (default: Single)'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
required: []
|
|
28
|
+
});
|
|
31
29
|
this.unityConnection = unityConnection;
|
|
32
30
|
}
|
|
33
31
|
|
|
@@ -38,17 +36,17 @@ export class SceneLoadToolHandler extends BaseToolHandler {
|
|
|
38
36
|
*/
|
|
39
37
|
validate(params) {
|
|
40
38
|
// Don't call super.validate() since we have no required fields
|
|
41
|
-
|
|
39
|
+
|
|
42
40
|
// Validate that either scenePath or sceneName is provided
|
|
43
41
|
if (!params.scenePath && !params.sceneName) {
|
|
44
42
|
throw new Error('Either scenePath or sceneName must be provided');
|
|
45
43
|
}
|
|
46
|
-
|
|
44
|
+
|
|
47
45
|
// Validate that only one is provided
|
|
48
46
|
if (params.scenePath && params.sceneName) {
|
|
49
47
|
throw new Error('Provide either scenePath or sceneName, not both');
|
|
50
48
|
}
|
|
51
|
-
|
|
49
|
+
|
|
52
50
|
// Validate load mode
|
|
53
51
|
if (params.loadMode && !['Single', 'Additive'].includes(params.loadMode)) {
|
|
54
52
|
throw new Error('Invalid load mode. Must be "Single" or "Additive"');
|
|
@@ -65,17 +63,17 @@ export class SceneLoadToolHandler extends BaseToolHandler {
|
|
|
65
63
|
if (!this.unityConnection.isConnected()) {
|
|
66
64
|
throw new Error('Unity connection not available');
|
|
67
65
|
}
|
|
68
|
-
|
|
66
|
+
|
|
69
67
|
// Send command to Unity
|
|
70
68
|
const result = await this.unityConnection.sendCommand('load_scene', params);
|
|
71
|
-
|
|
69
|
+
|
|
72
70
|
// Check for Unity-side errors
|
|
73
71
|
if (result.status === 'error') {
|
|
74
72
|
const error = new Error(result.error);
|
|
75
73
|
error.code = 'UNITY_ERROR';
|
|
76
74
|
throw error;
|
|
77
75
|
}
|
|
78
|
-
|
|
76
|
+
|
|
79
77
|
// Handle undefined or null results from Unity
|
|
80
78
|
if (result.result === undefined || result.result === null) {
|
|
81
79
|
return {
|
|
@@ -86,7 +84,7 @@ export class SceneLoadToolHandler extends BaseToolHandler {
|
|
|
86
84
|
message: 'Scene operation completed but Unity returned no details'
|
|
87
85
|
};
|
|
88
86
|
}
|
|
89
|
-
|
|
87
|
+
|
|
90
88
|
return result.result;
|
|
91
89
|
}
|
|
92
90
|
}
|
|
@@ -5,24 +5,21 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export class SceneSaveToolHandler extends BaseToolHandler {
|
|
7
7
|
constructor(unityConnection) {
|
|
8
|
-
super(
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
type: 'string',
|
|
16
|
-
description: 'Path where to save the scene. If not provided, saves to current scene path. Required if saveAs is true.'
|
|
17
|
-
},
|
|
18
|
-
saveAs: {
|
|
19
|
-
type: 'boolean',
|
|
20
|
-
description: 'Whether to save as a new scene (creates a copy). Default: false'
|
|
21
|
-
}
|
|
8
|
+
super('scene_save', 'Save current scene or save as a specified path.', {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
scenePath: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
description:
|
|
14
|
+
'Path where to save the scene. If not provided, saves to current scene path. Required if saveAs is true.'
|
|
22
15
|
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
saveAs: {
|
|
17
|
+
type: 'boolean',
|
|
18
|
+
description: 'Whether to save as a new scene (creates a copy). Default: false'
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
required: []
|
|
22
|
+
});
|
|
26
23
|
this.unityConnection = unityConnection;
|
|
27
24
|
}
|
|
28
25
|
|
|
@@ -33,7 +30,7 @@ export class SceneSaveToolHandler extends BaseToolHandler {
|
|
|
33
30
|
*/
|
|
34
31
|
validate(params) {
|
|
35
32
|
// Don't call super.validate() since we have no required fields
|
|
36
|
-
|
|
33
|
+
|
|
37
34
|
// Validate saveAs requires scenePath
|
|
38
35
|
if (params.saveAs && !params.scenePath) {
|
|
39
36
|
throw new Error('scenePath is required when saveAs is true');
|
|
@@ -50,17 +47,17 @@ export class SceneSaveToolHandler extends BaseToolHandler {
|
|
|
50
47
|
if (!this.unityConnection.isConnected()) {
|
|
51
48
|
throw new Error('Unity connection not available');
|
|
52
49
|
}
|
|
53
|
-
|
|
50
|
+
|
|
54
51
|
// Send command to Unity
|
|
55
52
|
const result = await this.unityConnection.sendCommand('save_scene', params);
|
|
56
|
-
|
|
53
|
+
|
|
57
54
|
// Check for Unity-side errors
|
|
58
55
|
if (result.status === 'error') {
|
|
59
56
|
const error = new Error(result.error);
|
|
60
57
|
error.code = 'UNITY_ERROR';
|
|
61
58
|
throw error;
|
|
62
59
|
}
|
|
63
|
-
|
|
60
|
+
|
|
64
61
|
// Handle undefined or null results from Unity
|
|
65
62
|
if (result.result === undefined || result.result === null) {
|
|
66
63
|
return {
|
|
@@ -70,7 +67,7 @@ export class SceneSaveToolHandler extends BaseToolHandler {
|
|
|
70
67
|
message: 'Scene save completed but Unity returned no details'
|
|
71
68
|
};
|
|
72
69
|
}
|
|
73
|
-
|
|
70
|
+
|
|
74
71
|
return result.result;
|
|
75
72
|
}
|
|
76
73
|
}
|
|
@@ -14,27 +14,33 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
14
14
|
captureMode: {
|
|
15
15
|
type: 'string',
|
|
16
16
|
enum: ['game', 'scene', 'window', 'explorer'],
|
|
17
|
-
description:
|
|
17
|
+
description:
|
|
18
|
+
'Capture mode selection:\n- "game": Game View (player\'s perspective, what the user sees)\n- "scene": Scene View (editor\'s 3D workspace view)\n- "explorer": AI/LLM exploration mode (optimized view for understanding scene content)\n- "window": Specific Unity Editor window by name'
|
|
18
19
|
},
|
|
19
20
|
width: {
|
|
20
21
|
type: 'number',
|
|
21
|
-
description:
|
|
22
|
+
description:
|
|
23
|
+
'Screenshot width in pixels (0 = use current view size). Range: 1-8192. Not applicable for explorer mode (use explorerSettings.camera.width instead)'
|
|
22
24
|
},
|
|
23
25
|
height: {
|
|
24
26
|
type: 'number',
|
|
25
|
-
description:
|
|
27
|
+
description:
|
|
28
|
+
'Screenshot height in pixels (0 = use current view size). Range: 1-8192. Not applicable for explorer mode (use explorerSettings.camera.height instead)'
|
|
26
29
|
},
|
|
27
30
|
includeUI: {
|
|
28
31
|
type: 'boolean',
|
|
29
|
-
description:
|
|
32
|
+
description:
|
|
33
|
+
'Whether to include UI overlay elements in Game View captures. Set to false for clean gameplay screenshots (default: true)'
|
|
30
34
|
},
|
|
31
35
|
windowName: {
|
|
32
36
|
type: 'string',
|
|
33
|
-
description:
|
|
37
|
+
description:
|
|
38
|
+
'Name of the Unity Editor window to capture (required when captureMode is "window"). Examples: "Console", "Inspector", "Hierarchy", "Project"'
|
|
34
39
|
},
|
|
35
40
|
encodeAsBase64: {
|
|
36
41
|
type: 'boolean',
|
|
37
|
-
description:
|
|
42
|
+
description:
|
|
43
|
+
'Return screenshot data as base64 string for immediate processing/analysis without file I/O (default: false)'
|
|
38
44
|
},
|
|
39
45
|
explorerSettings: {
|
|
40
46
|
type: 'object',
|
|
@@ -47,15 +53,18 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
47
53
|
type: {
|
|
48
54
|
type: 'string',
|
|
49
55
|
enum: ['gameObject', 'tag', 'area', 'position'],
|
|
50
|
-
description:
|
|
56
|
+
description:
|
|
57
|
+
'Target selection method:\n- "gameObject": Focus on a specific GameObject by name\n- "tag": Focus on all objects with a specific tag\n- "area": Focus on a circular area defined by center and radius\n- "position": Manual camera positioning without auto-framing'
|
|
51
58
|
},
|
|
52
59
|
name: {
|
|
53
60
|
type: 'string',
|
|
54
|
-
description:
|
|
61
|
+
description:
|
|
62
|
+
'GameObject name to target (required for "gameObject" type). Example: "Player", "MainCamera", "Enemy_01"'
|
|
55
63
|
},
|
|
56
64
|
tag: {
|
|
57
65
|
type: 'string',
|
|
58
|
-
description:
|
|
66
|
+
description:
|
|
67
|
+
'Tag to search for GameObjects (required for "tag" type). Example: "Enemy", "Collectible", "Player"'
|
|
59
68
|
},
|
|
60
69
|
center: {
|
|
61
70
|
type: 'object',
|
|
@@ -68,11 +77,13 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
68
77
|
},
|
|
69
78
|
radius: {
|
|
70
79
|
type: 'number',
|
|
71
|
-
description:
|
|
80
|
+
description:
|
|
81
|
+
'Radius around center for area targeting (used with "area" type). Defines the circular area to capture'
|
|
72
82
|
},
|
|
73
83
|
includeChildren: {
|
|
74
84
|
type: 'boolean',
|
|
75
|
-
description:
|
|
85
|
+
description:
|
|
86
|
+
'Include child objects when calculating the target bounds for framing (default: true)'
|
|
76
87
|
}
|
|
77
88
|
}
|
|
78
89
|
},
|
|
@@ -109,24 +120,29 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
109
120
|
},
|
|
110
121
|
fieldOfView: {
|
|
111
122
|
type: 'number',
|
|
112
|
-
|
|
113
|
-
description:
|
|
123
|
+
|
|
124
|
+
description:
|
|
125
|
+
'Camera field of view in degrees (1-179). Lower values zoom in, higher values zoom out'
|
|
114
126
|
},
|
|
115
127
|
nearClip: {
|
|
116
128
|
type: 'number',
|
|
117
|
-
description:
|
|
129
|
+
description:
|
|
130
|
+
"Near clipping plane distance. Objects closer than this won't be rendered (default: 0.3)"
|
|
118
131
|
},
|
|
119
132
|
farClip: {
|
|
120
133
|
type: 'number',
|
|
121
|
-
description:
|
|
134
|
+
description:
|
|
135
|
+
"Far clipping plane distance. Objects farther than this won't be rendered"
|
|
122
136
|
},
|
|
123
137
|
autoFrame: {
|
|
124
138
|
type: 'boolean',
|
|
125
|
-
description:
|
|
139
|
+
description:
|
|
140
|
+
'Automatically position camera to frame the target. Disable for manual positioning (default: true)'
|
|
126
141
|
},
|
|
127
142
|
padding: {
|
|
128
143
|
type: 'number',
|
|
129
|
-
description:
|
|
144
|
+
description:
|
|
145
|
+
'Padding around target when auto-framing (0-1). 0 = tight fit, 1 = lots of space (default: 0.2)'
|
|
130
146
|
},
|
|
131
147
|
offset: {
|
|
132
148
|
type: 'object',
|
|
@@ -164,11 +180,13 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
164
180
|
layers: {
|
|
165
181
|
type: 'array',
|
|
166
182
|
items: { type: 'string' },
|
|
167
|
-
description:
|
|
183
|
+
description:
|
|
184
|
+
'Unity layer names to include in rendering. If not specified, all layers are included. Examples: ["Default", "UI", "Player"]'
|
|
168
185
|
},
|
|
169
186
|
showGizmos: {
|
|
170
187
|
type: 'boolean',
|
|
171
|
-
description:
|
|
188
|
+
description:
|
|
189
|
+
'Show editor gizmos (transform handles, icons) in the capture (default: false)'
|
|
172
190
|
},
|
|
173
191
|
showColliders: {
|
|
174
192
|
type: 'boolean',
|
|
@@ -180,7 +198,8 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
180
198
|
},
|
|
181
199
|
highlightTarget: {
|
|
182
200
|
type: 'boolean',
|
|
183
|
-
description:
|
|
201
|
+
description:
|
|
202
|
+
'Highlight the target object(s) with an outline or color (default: false)'
|
|
184
203
|
}
|
|
185
204
|
}
|
|
186
205
|
}
|
|
@@ -190,7 +209,7 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
190
209
|
required: []
|
|
191
210
|
}
|
|
192
211
|
);
|
|
193
|
-
|
|
212
|
+
|
|
194
213
|
this.unityConnection = unityConnection;
|
|
195
214
|
}
|
|
196
215
|
|
|
@@ -213,119 +232,119 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
213
232
|
if (captureMode === 'window' && !windowName) {
|
|
214
233
|
throw new Error(
|
|
215
234
|
'windowName is required when captureMode is "window". ' +
|
|
216
|
-
|
|
235
|
+
'Specify the name of the Unity Editor window to capture (e.g., "Console", "Inspector", "Hierarchy")'
|
|
217
236
|
);
|
|
218
237
|
}
|
|
219
238
|
|
|
220
239
|
// Explorer mode validation
|
|
221
240
|
if (captureMode === 'explorer' && explorerSettings) {
|
|
222
241
|
const { target, camera, display } = explorerSettings;
|
|
223
|
-
|
|
242
|
+
|
|
224
243
|
// Validate target settings
|
|
225
244
|
if (target) {
|
|
226
245
|
const { type } = target;
|
|
227
246
|
if (type && !['gameObject', 'tag', 'area', 'position'].includes(type)) {
|
|
228
247
|
throw new Error(
|
|
229
248
|
'Invalid target.type for explorer mode. Must be one of:\n' +
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
249
|
+
'- "gameObject": Focus on a specific GameObject by name\n' +
|
|
250
|
+
'- "tag": Focus on all objects with a specific tag\n' +
|
|
251
|
+
'- "area": Focus on a circular area (center + radius)\n' +
|
|
252
|
+
'- "position": Manual camera positioning'
|
|
234
253
|
);
|
|
235
254
|
}
|
|
236
|
-
|
|
255
|
+
|
|
237
256
|
if (type === 'gameObject' && !target.name) {
|
|
238
257
|
throw new Error(
|
|
239
258
|
'target.name is required when target.type is "gameObject". ' +
|
|
240
|
-
|
|
259
|
+
'Specify the name of the GameObject to focus on (e.g., "Player", "MainCamera")'
|
|
241
260
|
);
|
|
242
261
|
}
|
|
243
|
-
|
|
262
|
+
|
|
244
263
|
if (type === 'tag' && !target.tag) {
|
|
245
264
|
throw new Error(
|
|
246
265
|
'target.tag is required when target.type is "tag". ' +
|
|
247
|
-
|
|
266
|
+
'Specify the tag to search for (e.g., "Enemy", "Collectible")'
|
|
248
267
|
);
|
|
249
268
|
}
|
|
250
|
-
|
|
269
|
+
|
|
251
270
|
if (type === 'area') {
|
|
252
271
|
if (!target.center) {
|
|
253
272
|
throw new Error(
|
|
254
273
|
'target.center is required when target.type is "area". ' +
|
|
255
|
-
|
|
274
|
+
'Specify the center position as {x, y, z} in world coordinates'
|
|
256
275
|
);
|
|
257
276
|
}
|
|
258
277
|
if (target.radius === undefined || target.radius <= 0) {
|
|
259
278
|
throw new Error(
|
|
260
279
|
'target.radius must be a positive number when target.type is "area". ' +
|
|
261
|
-
|
|
280
|
+
'Specify the radius of the area to capture'
|
|
262
281
|
);
|
|
263
282
|
}
|
|
264
283
|
}
|
|
265
284
|
}
|
|
266
|
-
|
|
285
|
+
|
|
267
286
|
// Validate camera settings
|
|
268
287
|
if (camera) {
|
|
269
288
|
if (camera.fieldOfView !== undefined) {
|
|
270
289
|
if (camera.fieldOfView < 1 || camera.fieldOfView > 179) {
|
|
271
290
|
throw new Error(
|
|
272
291
|
'camera.fieldOfView must be between 1 and 179 degrees. ' +
|
|
273
|
-
|
|
292
|
+
'Lower values (20-40) provide zoom effect, standard is 60, wide angle is 90+'
|
|
274
293
|
);
|
|
275
294
|
}
|
|
276
295
|
}
|
|
277
|
-
|
|
296
|
+
|
|
278
297
|
if (camera.padding !== undefined) {
|
|
279
298
|
if (camera.padding < 0 || camera.padding > 1) {
|
|
280
299
|
throw new Error(
|
|
281
300
|
'camera.padding must be between 0 and 1. ' +
|
|
282
|
-
|
|
301
|
+
'0 = tight framing, 0.2 = normal padding, 0.5+ = lots of surrounding space'
|
|
283
302
|
);
|
|
284
303
|
}
|
|
285
304
|
}
|
|
286
|
-
|
|
305
|
+
|
|
287
306
|
if (camera.width !== undefined) {
|
|
288
307
|
if (camera.width < 1 || camera.width > 8192) {
|
|
289
308
|
throw new Error(
|
|
290
309
|
'camera.width must be between 1 and 8192 pixels. ' +
|
|
291
|
-
|
|
310
|
+
'Common values: 1920 (Full HD), 2560 (2K), 3840 (4K)'
|
|
292
311
|
);
|
|
293
312
|
}
|
|
294
313
|
}
|
|
295
|
-
|
|
314
|
+
|
|
296
315
|
if (camera.height !== undefined) {
|
|
297
316
|
if (camera.height < 1 || camera.height > 8192) {
|
|
298
317
|
throw new Error(
|
|
299
318
|
'camera.height must be between 1 and 8192 pixels. ' +
|
|
300
|
-
|
|
319
|
+
'Common values: 1080 (Full HD), 1440 (2K), 2160 (4K)'
|
|
301
320
|
);
|
|
302
321
|
}
|
|
303
322
|
}
|
|
304
|
-
|
|
323
|
+
|
|
305
324
|
if (camera.nearClip !== undefined && camera.nearClip <= 0) {
|
|
306
325
|
throw new Error(
|
|
307
326
|
'camera.nearClip must be a positive number. ' +
|
|
308
|
-
|
|
327
|
+
'Typically 0.01 to 1.0 for close-up views, 0.3 is default'
|
|
309
328
|
);
|
|
310
329
|
}
|
|
311
|
-
|
|
330
|
+
|
|
312
331
|
if (camera.farClip !== undefined && camera.farClip <= 0) {
|
|
313
332
|
throw new Error(
|
|
314
333
|
'camera.farClip must be a positive number. ' +
|
|
315
|
-
|
|
334
|
+
'Should be larger than nearClip. Default is 1000, reduce for performance'
|
|
316
335
|
);
|
|
317
336
|
}
|
|
318
|
-
|
|
337
|
+
|
|
319
338
|
if (camera.nearClip !== undefined && camera.farClip !== undefined) {
|
|
320
339
|
if (camera.nearClip >= camera.farClip) {
|
|
321
340
|
throw new Error(
|
|
322
341
|
'camera.nearClip must be less than camera.farClip. ' +
|
|
323
|
-
|
|
342
|
+
'nearClip defines the closest visible distance, farClip the farthest'
|
|
324
343
|
);
|
|
325
344
|
}
|
|
326
345
|
}
|
|
327
346
|
}
|
|
328
|
-
|
|
347
|
+
|
|
329
348
|
// Validate display settings
|
|
330
349
|
if (display) {
|
|
331
350
|
if (display.backgroundColor) {
|
|
@@ -334,7 +353,7 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
334
353
|
if (value !== undefined && (value < 0 || value > 1)) {
|
|
335
354
|
throw new Error(
|
|
336
355
|
`backgroundColor.${name} must be between 0 and 1. ` +
|
|
337
|
-
|
|
356
|
+
'Color components use normalized values (0 = black/transparent, 1 = full intensity)'
|
|
338
357
|
);
|
|
339
358
|
}
|
|
340
359
|
};
|
|
@@ -343,11 +362,11 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
343
362
|
validateColorComponent(b, 'b');
|
|
344
363
|
validateColorComponent(a, 'a');
|
|
345
364
|
}
|
|
346
|
-
|
|
365
|
+
|
|
347
366
|
if (display.layers && !Array.isArray(display.layers)) {
|
|
348
367
|
throw new Error(
|
|
349
368
|
'display.layers must be an array of layer names. ' +
|
|
350
|
-
|
|
369
|
+
'Example: ["Default", "UI", "Player"]'
|
|
351
370
|
);
|
|
352
371
|
}
|
|
353
372
|
}
|
|
@@ -357,26 +376,26 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
357
376
|
if (outputPath) {
|
|
358
377
|
const validExtensions = ['.png', '.jpg', '.jpeg'];
|
|
359
378
|
const hasValidExtension = validExtensions.some(ext => outputPath.toLowerCase().endsWith(ext));
|
|
360
|
-
|
|
379
|
+
|
|
361
380
|
if (!hasValidExtension) {
|
|
362
381
|
throw new Error(
|
|
363
382
|
'outputPath must end with .png, .jpg, or .jpeg. ' +
|
|
364
|
-
|
|
383
|
+
'PNG is recommended for best quality, JPG for smaller file size'
|
|
365
384
|
);
|
|
366
385
|
}
|
|
367
|
-
|
|
386
|
+
|
|
368
387
|
if (!outputPath.startsWith('Assets/')) {
|
|
369
388
|
throw new Error(
|
|
370
389
|
'outputPath must be within the Assets folder. ' +
|
|
371
|
-
|
|
390
|
+
'Example: "Assets/Screenshots/capture.png"'
|
|
372
391
|
);
|
|
373
392
|
}
|
|
374
|
-
|
|
393
|
+
|
|
375
394
|
// Warn about potential path issues
|
|
376
395
|
if (outputPath.includes('\\')) {
|
|
377
396
|
throw new Error(
|
|
378
397
|
'outputPath should use forward slashes (/) not backslashes (\\). ' +
|
|
379
|
-
|
|
398
|
+
'Example: "Assets/Screenshots/capture.png"'
|
|
380
399
|
);
|
|
381
400
|
}
|
|
382
401
|
}
|
|
@@ -387,16 +406,16 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
387
406
|
if (params.width < 0 || params.width > 8192) {
|
|
388
407
|
throw new Error(
|
|
389
408
|
'width must be between 0 and 8192 pixels. ' +
|
|
390
|
-
|
|
409
|
+
'0 = use current view size, common values: 1920, 2560, 3840'
|
|
391
410
|
);
|
|
392
411
|
}
|
|
393
412
|
}
|
|
394
|
-
|
|
413
|
+
|
|
395
414
|
if (params.height !== undefined) {
|
|
396
415
|
if (params.height < 0 || params.height > 8192) {
|
|
397
416
|
throw new Error(
|
|
398
417
|
'height must be between 0 and 8192 pixels. ' +
|
|
399
|
-
|
|
418
|
+
'0 = use current view size, common values: 1080, 1440, 2160'
|
|
400
419
|
);
|
|
401
420
|
}
|
|
402
421
|
}
|
|
@@ -420,7 +439,10 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
420
439
|
|
|
421
440
|
// Send capture command to Unity
|
|
422
441
|
const { WORKSPACE_ROOT } = await import('../../core/config.js');
|
|
423
|
-
const response = await this.unityConnection.sendCommand('capture_screenshot', {
|
|
442
|
+
const response = await this.unityConnection.sendCommand('capture_screenshot', {
|
|
443
|
+
...(params || {}),
|
|
444
|
+
workspaceRoot: WORKSPACE_ROOT
|
|
445
|
+
});
|
|
424
446
|
|
|
425
447
|
// Handle Unity response
|
|
426
448
|
if (response.error) {
|
|
@@ -487,7 +509,7 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
487
509
|
outputPath: 'Assets/Screenshots/scene_4k.png'
|
|
488
510
|
}
|
|
489
511
|
},
|
|
490
|
-
|
|
512
|
+
|
|
491
513
|
// Explorer mode examples for AI/LLM usage
|
|
492
514
|
analyzePlayer: {
|
|
493
515
|
description: 'AI/LLM: Analyze the player character and its surroundings',
|
|
@@ -603,7 +625,7 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
603
625
|
}
|
|
604
626
|
},
|
|
605
627
|
birdEyeView: {
|
|
606
|
-
description:
|
|
628
|
+
description: "AI/LLM: Top-down bird's eye view of the entire level",
|
|
607
629
|
params: {
|
|
608
630
|
captureMode: 'explorer',
|
|
609
631
|
encodeAsBase64: true,
|
|
@@ -620,7 +642,7 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
620
642
|
}
|
|
621
643
|
}
|
|
622
644
|
},
|
|
623
|
-
|
|
645
|
+
|
|
624
646
|
// Window capture examples
|
|
625
647
|
captureConsole: {
|
|
626
648
|
description: 'Capture Unity console for error debugging',
|
|
@@ -637,7 +659,7 @@ export class ScreenshotCaptureToolHandler extends BaseToolHandler {
|
|
|
637
659
|
windowName: 'Inspector'
|
|
638
660
|
}
|
|
639
661
|
},
|
|
640
|
-
|
|
662
|
+
|
|
641
663
|
// Advanced explorer examples
|
|
642
664
|
cinematicShot: {
|
|
643
665
|
description: 'AI/LLM: Cinematic angle shot of a specific scene moment',
|