unreal-engine-mcp-server 0.4.0 → 0.4.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/.env.production +1 -1
- package/.github/copilot-instructions.md +45 -0
- package/.github/workflows/publish-mcp.yml +1 -1
- package/README.md +21 -5
- package/dist/index.js +124 -31
- package/dist/prompts/index.d.ts +10 -3
- package/dist/prompts/index.js +186 -7
- package/dist/resources/actors.d.ts +19 -1
- package/dist/resources/actors.js +55 -64
- package/dist/resources/assets.js +46 -62
- package/dist/resources/levels.d.ts +21 -3
- package/dist/resources/levels.js +29 -54
- package/dist/tools/actors.d.ts +3 -14
- package/dist/tools/actors.js +246 -302
- package/dist/tools/animation.d.ts +57 -102
- package/dist/tools/animation.js +429 -450
- package/dist/tools/assets.d.ts +13 -2
- package/dist/tools/assets.js +52 -44
- package/dist/tools/audio.d.ts +22 -13
- package/dist/tools/audio.js +467 -121
- package/dist/tools/blueprint.d.ts +32 -13
- package/dist/tools/blueprint.js +699 -448
- package/dist/tools/build_environment_advanced.d.ts +0 -1
- package/dist/tools/build_environment_advanced.js +190 -45
- package/dist/tools/consolidated-tool-definitions.js +78 -252
- package/dist/tools/consolidated-tool-handlers.js +506 -133
- package/dist/tools/debug.d.ts +72 -10
- package/dist/tools/debug.js +167 -31
- package/dist/tools/editor.d.ts +9 -2
- package/dist/tools/editor.js +30 -44
- package/dist/tools/foliage.d.ts +34 -15
- package/dist/tools/foliage.js +97 -107
- package/dist/tools/introspection.js +19 -21
- package/dist/tools/landscape.d.ts +1 -2
- package/dist/tools/landscape.js +311 -168
- package/dist/tools/level.d.ts +3 -28
- package/dist/tools/level.js +642 -192
- package/dist/tools/lighting.d.ts +14 -3
- package/dist/tools/lighting.js +236 -123
- package/dist/tools/materials.d.ts +25 -7
- package/dist/tools/materials.js +102 -79
- package/dist/tools/niagara.d.ts +10 -12
- package/dist/tools/niagara.js +74 -94
- package/dist/tools/performance.d.ts +12 -4
- package/dist/tools/performance.js +38 -79
- package/dist/tools/physics.d.ts +34 -10
- package/dist/tools/physics.js +364 -292
- package/dist/tools/rc.js +97 -23
- package/dist/tools/sequence.d.ts +1 -0
- package/dist/tools/sequence.js +125 -22
- package/dist/tools/ui.d.ts +31 -4
- package/dist/tools/ui.js +83 -66
- package/dist/tools/visual.d.ts +11 -0
- package/dist/tools/visual.js +245 -30
- package/dist/types/tool-types.d.ts +0 -6
- package/dist/types/tool-types.js +1 -8
- package/dist/unreal-bridge.d.ts +32 -2
- package/dist/unreal-bridge.js +621 -127
- package/dist/utils/elicitation.d.ts +57 -0
- package/dist/utils/elicitation.js +104 -0
- package/dist/utils/error-handler.d.ts +0 -33
- package/dist/utils/error-handler.js +4 -111
- package/dist/utils/http.d.ts +2 -22
- package/dist/utils/http.js +12 -75
- package/dist/utils/normalize.d.ts +4 -4
- package/dist/utils/normalize.js +15 -7
- package/dist/utils/python-output.d.ts +18 -0
- package/dist/utils/python-output.js +290 -0
- package/dist/utils/python.d.ts +2 -0
- package/dist/utils/python.js +4 -0
- package/dist/utils/response-validator.js +28 -2
- package/dist/utils/result-helpers.d.ts +27 -0
- package/dist/utils/result-helpers.js +147 -0
- package/dist/utils/safe-json.d.ts +0 -2
- package/dist/utils/safe-json.js +0 -43
- package/dist/utils/validation.d.ts +16 -0
- package/dist/utils/validation.js +70 -7
- package/mcp-config-example.json +2 -2
- package/package.json +10 -9
- package/server.json +37 -14
- package/src/index.ts +130 -33
- package/src/prompts/index.ts +211 -13
- package/src/resources/actors.ts +59 -44
- package/src/resources/assets.ts +48 -51
- package/src/resources/levels.ts +35 -45
- package/src/tools/actors.ts +269 -313
- package/src/tools/animation.ts +556 -539
- package/src/tools/assets.ts +53 -43
- package/src/tools/audio.ts +507 -113
- package/src/tools/blueprint.ts +778 -462
- package/src/tools/build_environment_advanced.ts +266 -64
- package/src/tools/consolidated-tool-definitions.ts +90 -264
- package/src/tools/consolidated-tool-handlers.ts +630 -121
- package/src/tools/debug.ts +176 -33
- package/src/tools/editor.ts +35 -37
- package/src/tools/foliage.ts +110 -104
- package/src/tools/introspection.ts +24 -22
- package/src/tools/landscape.ts +334 -181
- package/src/tools/level.ts +683 -182
- package/src/tools/lighting.ts +244 -123
- package/src/tools/materials.ts +114 -83
- package/src/tools/niagara.ts +87 -81
- package/src/tools/performance.ts +49 -88
- package/src/tools/physics.ts +393 -299
- package/src/tools/rc.ts +102 -24
- package/src/tools/sequence.ts +136 -28
- package/src/tools/ui.ts +101 -70
- package/src/tools/visual.ts +250 -29
- package/src/types/tool-types.ts +0 -9
- package/src/unreal-bridge.ts +658 -140
- package/src/utils/elicitation.ts +129 -0
- package/src/utils/error-handler.ts +4 -159
- package/src/utils/http.ts +16 -115
- package/src/utils/normalize.ts +20 -10
- package/src/utils/python-output.ts +351 -0
- package/src/utils/python.ts +3 -0
- package/src/utils/response-validator.ts +25 -2
- package/src/utils/result-helpers.ts +193 -0
- package/src/utils/safe-json.ts +0 -50
- package/src/utils/validation.ts +94 -7
- package/tests/run-unreal-tool-tests.mjs +720 -0
- package/tsconfig.json +2 -2
- package/dist/python-utils.d.ts +0 -29
- package/dist/python-utils.js +0 -54
- package/dist/types/index.d.ts +0 -323
- package/dist/types/index.js +0 -28
- package/dist/utils/cache-manager.d.ts +0 -64
- package/dist/utils/cache-manager.js +0 -176
- package/dist/utils/errors.d.ts +0 -133
- package/dist/utils/errors.js +0 -256
- package/src/python/editor_compat.py +0 -181
- package/src/python-utils.ts +0 -57
- package/src/types/index.ts +0 -414
- package/src/utils/cache-manager.ts +0 -213
- package/src/utils/errors.ts +0 -312
package/dist/tools/debug.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { UnrealBridge } from '../unreal-bridge.js';
|
|
|
2
2
|
export declare class DebugVisualizationTools {
|
|
3
3
|
private bridge;
|
|
4
4
|
constructor(bridge: UnrealBridge);
|
|
5
|
-
private _executeCommand;
|
|
6
5
|
private pyDraw;
|
|
7
6
|
drawDebugLine(params: {
|
|
8
7
|
start: [number, number, number];
|
|
@@ -12,10 +11,17 @@ export declare class DebugVisualizationTools {
|
|
|
12
11
|
thickness?: number;
|
|
13
12
|
}): Promise<{
|
|
14
13
|
success: boolean;
|
|
15
|
-
|
|
14
|
+
action: string;
|
|
15
|
+
warnings: string[] | undefined;
|
|
16
|
+
details: string[] | undefined;
|
|
17
|
+
rawOutput: string | undefined;
|
|
18
|
+
raw: unknown;
|
|
19
|
+
message?: string;
|
|
20
|
+
error?: string;
|
|
16
21
|
} | {
|
|
17
22
|
success: boolean;
|
|
18
23
|
error: string;
|
|
24
|
+
action: string;
|
|
19
25
|
}>;
|
|
20
26
|
drawDebugBox(params: {
|
|
21
27
|
center: [number, number, number];
|
|
@@ -26,10 +32,17 @@ export declare class DebugVisualizationTools {
|
|
|
26
32
|
thickness?: number;
|
|
27
33
|
}): Promise<{
|
|
28
34
|
success: boolean;
|
|
29
|
-
|
|
35
|
+
action: string;
|
|
36
|
+
warnings: string[] | undefined;
|
|
37
|
+
details: string[] | undefined;
|
|
38
|
+
rawOutput: string | undefined;
|
|
39
|
+
raw: unknown;
|
|
40
|
+
message?: string;
|
|
41
|
+
error?: string;
|
|
30
42
|
} | {
|
|
31
43
|
success: boolean;
|
|
32
44
|
error: string;
|
|
45
|
+
action: string;
|
|
33
46
|
}>;
|
|
34
47
|
drawDebugSphere(params: {
|
|
35
48
|
center: [number, number, number];
|
|
@@ -40,10 +53,17 @@ export declare class DebugVisualizationTools {
|
|
|
40
53
|
thickness?: number;
|
|
41
54
|
}): Promise<{
|
|
42
55
|
success: boolean;
|
|
43
|
-
|
|
56
|
+
action: string;
|
|
57
|
+
warnings: string[] | undefined;
|
|
58
|
+
details: string[] | undefined;
|
|
59
|
+
rawOutput: string | undefined;
|
|
60
|
+
raw: unknown;
|
|
61
|
+
message?: string;
|
|
62
|
+
error?: string;
|
|
44
63
|
} | {
|
|
45
64
|
success: boolean;
|
|
46
65
|
error: string;
|
|
66
|
+
action: string;
|
|
47
67
|
}>;
|
|
48
68
|
drawDebugCapsule(params: {
|
|
49
69
|
center: [number, number, number];
|
|
@@ -54,10 +74,17 @@ export declare class DebugVisualizationTools {
|
|
|
54
74
|
duration?: number;
|
|
55
75
|
}): Promise<{
|
|
56
76
|
success: boolean;
|
|
57
|
-
|
|
77
|
+
action: string;
|
|
78
|
+
warnings: string[] | undefined;
|
|
79
|
+
details: string[] | undefined;
|
|
80
|
+
rawOutput: string | undefined;
|
|
81
|
+
raw: unknown;
|
|
82
|
+
message?: string;
|
|
83
|
+
error?: string;
|
|
58
84
|
} | {
|
|
59
85
|
success: boolean;
|
|
60
86
|
error: string;
|
|
87
|
+
action: string;
|
|
61
88
|
}>;
|
|
62
89
|
drawDebugCone(params: {
|
|
63
90
|
origin: [number, number, number];
|
|
@@ -70,10 +97,17 @@ export declare class DebugVisualizationTools {
|
|
|
70
97
|
duration?: number;
|
|
71
98
|
}): Promise<{
|
|
72
99
|
success: boolean;
|
|
73
|
-
|
|
100
|
+
action: string;
|
|
101
|
+
warnings: string[] | undefined;
|
|
102
|
+
details: string[] | undefined;
|
|
103
|
+
rawOutput: string | undefined;
|
|
104
|
+
raw: unknown;
|
|
105
|
+
message?: string;
|
|
106
|
+
error?: string;
|
|
74
107
|
} | {
|
|
75
108
|
success: boolean;
|
|
76
109
|
error: string;
|
|
110
|
+
action: string;
|
|
77
111
|
}>;
|
|
78
112
|
drawDebugString(params: {
|
|
79
113
|
location: [number, number, number];
|
|
@@ -83,10 +117,17 @@ export declare class DebugVisualizationTools {
|
|
|
83
117
|
fontSize?: number;
|
|
84
118
|
}): Promise<{
|
|
85
119
|
success: boolean;
|
|
86
|
-
|
|
120
|
+
action: string;
|
|
121
|
+
warnings: string[] | undefined;
|
|
122
|
+
details: string[] | undefined;
|
|
123
|
+
rawOutput: string | undefined;
|
|
124
|
+
raw: unknown;
|
|
125
|
+
message?: string;
|
|
126
|
+
error?: string;
|
|
87
127
|
} | {
|
|
88
128
|
success: boolean;
|
|
89
129
|
error: string;
|
|
130
|
+
action: string;
|
|
90
131
|
}>;
|
|
91
132
|
drawDebugArrow(params: {
|
|
92
133
|
start: [number, number, number];
|
|
@@ -97,10 +138,17 @@ export declare class DebugVisualizationTools {
|
|
|
97
138
|
thickness?: number;
|
|
98
139
|
}): Promise<{
|
|
99
140
|
success: boolean;
|
|
100
|
-
|
|
141
|
+
action: string;
|
|
142
|
+
warnings: string[] | undefined;
|
|
143
|
+
details: string[] | undefined;
|
|
144
|
+
rawOutput: string | undefined;
|
|
145
|
+
raw: unknown;
|
|
146
|
+
message?: string;
|
|
147
|
+
error?: string;
|
|
101
148
|
} | {
|
|
102
149
|
success: boolean;
|
|
103
150
|
error: string;
|
|
151
|
+
action: string;
|
|
104
152
|
}>;
|
|
105
153
|
drawDebugPoint(params: {
|
|
106
154
|
location: [number, number, number];
|
|
@@ -109,10 +157,17 @@ export declare class DebugVisualizationTools {
|
|
|
109
157
|
duration?: number;
|
|
110
158
|
}): Promise<{
|
|
111
159
|
success: boolean;
|
|
112
|
-
|
|
160
|
+
action: string;
|
|
161
|
+
warnings: string[] | undefined;
|
|
162
|
+
details: string[] | undefined;
|
|
163
|
+
rawOutput: string | undefined;
|
|
164
|
+
raw: unknown;
|
|
165
|
+
message?: string;
|
|
166
|
+
error?: string;
|
|
113
167
|
} | {
|
|
114
168
|
success: boolean;
|
|
115
169
|
error: string;
|
|
170
|
+
action: string;
|
|
116
171
|
}>;
|
|
117
172
|
drawDebugCoordinateSystem(params: {
|
|
118
173
|
location: [number, number, number];
|
|
@@ -132,10 +187,17 @@ export declare class DebugVisualizationTools {
|
|
|
132
187
|
duration?: number;
|
|
133
188
|
}): Promise<{
|
|
134
189
|
success: boolean;
|
|
135
|
-
|
|
190
|
+
action: string;
|
|
191
|
+
warnings: string[] | undefined;
|
|
192
|
+
details: string[] | undefined;
|
|
193
|
+
rawOutput: string | undefined;
|
|
194
|
+
raw: unknown;
|
|
195
|
+
message?: string;
|
|
196
|
+
error?: string;
|
|
136
197
|
} | {
|
|
137
198
|
success: boolean;
|
|
138
199
|
error: string;
|
|
200
|
+
action: string;
|
|
139
201
|
}>;
|
|
140
202
|
clearDebugDrawings(): Promise<any>;
|
|
141
203
|
showCollision(params: {
|
package/dist/tools/debug.js
CHANGED
|
@@ -1,39 +1,87 @@
|
|
|
1
|
+
import { bestEffortInterpretedText, coerceString, interpretStandardResult } from '../utils/result-helpers.js';
|
|
2
|
+
import { parseStandardResult } from '../utils/python-output.js';
|
|
1
3
|
export class DebugVisualizationTools {
|
|
2
4
|
bridge;
|
|
3
5
|
constructor(bridge) {
|
|
4
6
|
this.bridge = bridge;
|
|
5
7
|
}
|
|
6
|
-
// Execute console command (kept for legacy operations)
|
|
7
|
-
async _executeCommand(command) {
|
|
8
|
-
return this.bridge.httpCall('/remote/object/call', 'PUT', {
|
|
9
|
-
objectPath: '/Script/Engine.Default__KismetSystemLibrary',
|
|
10
|
-
functionName: 'ExecuteConsoleCommand',
|
|
11
|
-
parameters: {
|
|
12
|
-
WorldContextObject: null,
|
|
13
|
-
Command: command,
|
|
14
|
-
SpecificPlayer: null
|
|
15
|
-
},
|
|
16
|
-
generateTransaction: false
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
8
|
// Helper to draw via Python SystemLibrary with the editor world
|
|
20
|
-
async pyDraw(scriptBody) {
|
|
9
|
+
async pyDraw(scriptBody, meta) {
|
|
10
|
+
const action = (meta?.action || 'debug_draw').replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
11
|
+
const payloadObject = meta?.params ?? {};
|
|
12
|
+
const payloadJson = JSON.stringify(payloadObject).replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
13
|
+
const indentedBody = scriptBody
|
|
14
|
+
.split(/\r?\n/)
|
|
15
|
+
.map(line => ` ${line}`)
|
|
16
|
+
.join('\n');
|
|
21
17
|
const script = `
|
|
22
18
|
import unreal
|
|
23
|
-
|
|
19
|
+
import json
|
|
20
|
+
|
|
21
|
+
payload = json.loads('${payloadJson}')
|
|
24
22
|
ues = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
|
|
25
23
|
if not ues:
|
|
26
24
|
raise Exception('UnrealEditorSubsystem not available')
|
|
27
25
|
world = ues.get_editor_world()
|
|
28
|
-
|
|
26
|
+
if not world:
|
|
27
|
+
raise Exception('Editor world unavailable')
|
|
28
|
+
try:
|
|
29
|
+
${indentedBody}
|
|
30
|
+
print('DEBUG_DRAW:' + json.dumps({'action': '${action}', 'params': payload}))
|
|
31
|
+
print('RESULT:' + json.dumps({'success': True, 'action': '${action}', 'params': payload}))
|
|
32
|
+
except Exception as e:
|
|
33
|
+
print('DEBUG_DRAW_ERROR:' + str(e))
|
|
34
|
+
print('RESULT:' + json.dumps({'success': False, 'action': '${action}', 'error': str(e)}))
|
|
29
35
|
`.trim()
|
|
30
36
|
.replace(/\r?\n/g, '\n');
|
|
31
37
|
try {
|
|
32
|
-
await this.bridge.executePython(script);
|
|
33
|
-
|
|
38
|
+
const response = await this.bridge.executePython(script);
|
|
39
|
+
let interpreted = interpretStandardResult(response, {
|
|
40
|
+
successMessage: `${action} executed`,
|
|
41
|
+
failureMessage: `${action} failed`
|
|
42
|
+
});
|
|
43
|
+
const parsed = parseStandardResult(response);
|
|
44
|
+
const parsedPayload = parsed.data ?? {};
|
|
45
|
+
const parsedSuccessValue = parsedPayload.success;
|
|
46
|
+
const normalizedSuccess = typeof parsedSuccessValue === 'string'
|
|
47
|
+
? ['true', '1', 'yes'].includes(parsedSuccessValue.toLowerCase())
|
|
48
|
+
: parsedSuccessValue === true;
|
|
49
|
+
if (!interpreted.success && normalizedSuccess) {
|
|
50
|
+
interpreted = {
|
|
51
|
+
...interpreted,
|
|
52
|
+
success: true,
|
|
53
|
+
error: undefined,
|
|
54
|
+
message: interpreted.message || `${action} executed`,
|
|
55
|
+
payload: { ...parsedPayload }
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const finalSuccess = interpreted.success || normalizedSuccess;
|
|
59
|
+
const resolvedAction = coerceString(interpreted.payload.action) ?? action;
|
|
60
|
+
const fallbackOutput = typeof parsed.text === 'string' ? parsed.text : '';
|
|
61
|
+
const rawOutput = bestEffortInterpretedText(interpreted) ?? (fallbackOutput ? fallbackOutput : undefined);
|
|
62
|
+
if (finalSuccess) {
|
|
63
|
+
return {
|
|
64
|
+
...interpreted.payload,
|
|
65
|
+
success: true,
|
|
66
|
+
action: resolvedAction,
|
|
67
|
+
warnings: interpreted.warnings,
|
|
68
|
+
details: interpreted.details,
|
|
69
|
+
rawOutput,
|
|
70
|
+
raw: parsed.raw ?? interpreted.raw
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
action: resolvedAction,
|
|
76
|
+
error: interpreted.error ?? `${resolvedAction} failed`,
|
|
77
|
+
warnings: interpreted.warnings,
|
|
78
|
+
details: interpreted.details,
|
|
79
|
+
rawOutput,
|
|
80
|
+
raw: parsed.raw ?? interpreted.raw
|
|
81
|
+
};
|
|
34
82
|
}
|
|
35
83
|
catch (e) {
|
|
36
|
-
return { success: false, error: String(e) };
|
|
84
|
+
return { success: false, error: String(e), action: meta?.action || 'debug_draw' };
|
|
37
85
|
}
|
|
38
86
|
}
|
|
39
87
|
// Draw debug line using Python SystemLibrary
|
|
@@ -50,7 +98,16 @@ end = unreal.Vector(${ex}, ${ey}, ${ez})
|
|
|
50
98
|
color = unreal.LinearColor(${sr}/255.0, ${sg}/255.0, ${sb}/255.0, ${sa}/255.0)
|
|
51
99
|
unreal.SystemLibrary.draw_debug_line(world, start, end, color, ${duration}, ${thickness})
|
|
52
100
|
`;
|
|
53
|
-
return this.pyDraw(script
|
|
101
|
+
return this.pyDraw(script, {
|
|
102
|
+
action: 'debug_line',
|
|
103
|
+
params: {
|
|
104
|
+
start: params.start,
|
|
105
|
+
end: params.end,
|
|
106
|
+
color,
|
|
107
|
+
duration,
|
|
108
|
+
thickness
|
|
109
|
+
}
|
|
110
|
+
});
|
|
54
111
|
}
|
|
55
112
|
// Draw debug box using Python SystemLibrary
|
|
56
113
|
async drawDebugBox(params) {
|
|
@@ -69,7 +126,17 @@ rot = unreal.Rotator(${rp}, ${ry}, ${rr})
|
|
|
69
126
|
color = unreal.LinearColor(${cr}/255.0, ${cg}/255.0, ${cb}/255.0, ${ca}/255.0)
|
|
70
127
|
unreal.SystemLibrary.draw_debug_box(world, center, extent, color, rot, ${duration}, ${thickness})
|
|
71
128
|
`;
|
|
72
|
-
return this.pyDraw(script
|
|
129
|
+
return this.pyDraw(script, {
|
|
130
|
+
action: 'debug_box',
|
|
131
|
+
params: {
|
|
132
|
+
center: params.center,
|
|
133
|
+
extent: params.extent,
|
|
134
|
+
rotation,
|
|
135
|
+
color,
|
|
136
|
+
duration,
|
|
137
|
+
thickness
|
|
138
|
+
}
|
|
139
|
+
});
|
|
73
140
|
}
|
|
74
141
|
// Draw debug sphere using Python SystemLibrary
|
|
75
142
|
async drawDebugSphere(params) {
|
|
@@ -84,7 +151,17 @@ center = unreal.Vector(${cx}, ${cy}, ${cz})
|
|
|
84
151
|
color = unreal.LinearColor(${cr}/255.0, ${cg}/255.0, ${cb}/255.0, ${ca}/255.0)
|
|
85
152
|
unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segments}, color, ${duration}, ${thickness})
|
|
86
153
|
`;
|
|
87
|
-
return this.pyDraw(script
|
|
154
|
+
return this.pyDraw(script, {
|
|
155
|
+
action: 'debug_sphere',
|
|
156
|
+
params: {
|
|
157
|
+
center: params.center,
|
|
158
|
+
radius: params.radius,
|
|
159
|
+
segments,
|
|
160
|
+
color,
|
|
161
|
+
duration,
|
|
162
|
+
thickness
|
|
163
|
+
}
|
|
164
|
+
});
|
|
88
165
|
}
|
|
89
166
|
// The rest keep console-command fallbacks or editor helpers as before
|
|
90
167
|
async drawDebugCapsule(params) {
|
|
@@ -95,7 +172,17 @@ unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segmen
|
|
|
95
172
|
const [rp, ry, rr] = rotation;
|
|
96
173
|
const [cr, cg, cb, ca] = color;
|
|
97
174
|
const script = `\ncenter = unreal.Vector(${cx}, ${cy}, ${cz})\nrot = unreal.Rotator(${rp}, ${ry}, ${rr})\ncolor = unreal.LinearColor(${cr}/255.0, ${cg}/255.0, ${cb}/255.0, ${ca}/255.0)\nunreal.SystemLibrary.draw_debug_capsule(world, center, ${params.halfHeight}, ${params.radius}, rot, color, ${duration}, 1.0)\n`;
|
|
98
|
-
return this.pyDraw(script
|
|
175
|
+
return this.pyDraw(script, {
|
|
176
|
+
action: 'debug_capsule',
|
|
177
|
+
params: {
|
|
178
|
+
center: params.center,
|
|
179
|
+
halfHeight: params.halfHeight,
|
|
180
|
+
radius: params.radius,
|
|
181
|
+
rotation,
|
|
182
|
+
color,
|
|
183
|
+
duration
|
|
184
|
+
}
|
|
185
|
+
});
|
|
99
186
|
}
|
|
100
187
|
async drawDebugCone(params) {
|
|
101
188
|
const color = params.color || [255, 0, 255, 255];
|
|
@@ -104,7 +191,19 @@ unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segmen
|
|
|
104
191
|
const [dx, dy, dz] = params.direction;
|
|
105
192
|
const [cr, cg, cb, ca] = color;
|
|
106
193
|
const script = `\norigin = unreal.Vector(${ox}, ${oy}, ${oz})\ndir = unreal.Vector(${dx}, ${dy}, ${dz})\ncolor = unreal.LinearColor(${cr}/255.0, ${cg}/255.0, ${cb}/255.0, ${ca}/255.0)\nunreal.SystemLibrary.draw_debug_cone(world, origin, dir, ${params.length}, ${params.angleWidth}, ${params.angleHeight}, ${params.numSides || 12}, color, ${duration}, 1.0)\n`;
|
|
107
|
-
return this.pyDraw(script
|
|
194
|
+
return this.pyDraw(script, {
|
|
195
|
+
action: 'debug_cone',
|
|
196
|
+
params: {
|
|
197
|
+
origin: params.origin,
|
|
198
|
+
direction: params.direction,
|
|
199
|
+
length: params.length,
|
|
200
|
+
angleWidth: params.angleWidth,
|
|
201
|
+
angleHeight: params.angleHeight,
|
|
202
|
+
numSides: params.numSides || 12,
|
|
203
|
+
color,
|
|
204
|
+
duration
|
|
205
|
+
}
|
|
206
|
+
});
|
|
108
207
|
}
|
|
109
208
|
async drawDebugString(params) {
|
|
110
209
|
const color = params.color || [255, 255, 255, 255];
|
|
@@ -112,7 +211,16 @@ unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segmen
|
|
|
112
211
|
const [x, y, z] = params.location;
|
|
113
212
|
const [r, g, b, a] = color;
|
|
114
213
|
const script = `\nloc = unreal.Vector(${x}, ${y}, ${z})\ncolor = unreal.LinearColor(${r}/255.0, ${g}/255.0, ${b}/255.0, ${a}/255.0)\nunreal.SystemLibrary.draw_debug_string(world, loc, "${params.text.replace(/"/g, '\\"')}", None, color, ${duration})\n`;
|
|
115
|
-
return this.pyDraw(script
|
|
214
|
+
return this.pyDraw(script, {
|
|
215
|
+
action: 'debug_string',
|
|
216
|
+
params: {
|
|
217
|
+
location: params.location,
|
|
218
|
+
text: params.text,
|
|
219
|
+
color,
|
|
220
|
+
duration,
|
|
221
|
+
fontSize: params.fontSize
|
|
222
|
+
}
|
|
223
|
+
});
|
|
116
224
|
}
|
|
117
225
|
async drawDebugArrow(params) {
|
|
118
226
|
const color = params.color || [0, 255, 255, 255];
|
|
@@ -122,7 +230,17 @@ unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segmen
|
|
|
122
230
|
const [ex, ey, ez] = params.end;
|
|
123
231
|
const [r, g, b, a] = color;
|
|
124
232
|
const script = `\nstart = unreal.Vector(${sx}, ${sy}, ${sz})\nend = unreal.Vector(${ex}, ${ey}, ${ez})\ncolor = unreal.LinearColor(${r}/255.0, ${g}/255.0, ${b}/255.0, ${a}/255.0)\nunreal.SystemLibrary.draw_debug_arrow(world, start, end, ${params.arrowSize || 10.0}, color, ${duration}, ${thickness})\n`;
|
|
125
|
-
return this.pyDraw(script
|
|
233
|
+
return this.pyDraw(script, {
|
|
234
|
+
action: 'debug_arrow',
|
|
235
|
+
params: {
|
|
236
|
+
start: params.start,
|
|
237
|
+
end: params.end,
|
|
238
|
+
arrowSize: params.arrowSize || 10.0,
|
|
239
|
+
color,
|
|
240
|
+
duration,
|
|
241
|
+
thickness
|
|
242
|
+
}
|
|
243
|
+
});
|
|
126
244
|
}
|
|
127
245
|
async drawDebugPoint(params) {
|
|
128
246
|
const size = params.size || 10.0;
|
|
@@ -131,7 +249,15 @@ unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segmen
|
|
|
131
249
|
const [x, y, z] = params.location;
|
|
132
250
|
const [r, g, b, a] = color;
|
|
133
251
|
const script = `\nloc = unreal.Vector(${x}, ${y}, ${z})\ncolor = unreal.LinearColor(${r}/255.0, ${g}/255.0, ${b}/255.0, ${a}/255.0)\nunreal.SystemLibrary.draw_debug_point(world, loc, ${size}, color, ${duration})\n`;
|
|
134
|
-
return this.pyDraw(script
|
|
252
|
+
return this.pyDraw(script, {
|
|
253
|
+
action: 'debug_point',
|
|
254
|
+
params: {
|
|
255
|
+
location: params.location,
|
|
256
|
+
size,
|
|
257
|
+
color,
|
|
258
|
+
duration
|
|
259
|
+
}
|
|
260
|
+
});
|
|
135
261
|
}
|
|
136
262
|
async drawDebugCoordinateSystem(params) {
|
|
137
263
|
const rotation = params.rotation || [0, 0, 0];
|
|
@@ -151,7 +277,19 @@ unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segmen
|
|
|
151
277
|
const [rp, ry, rr] = params.rotation;
|
|
152
278
|
const [r, g, b, a] = color;
|
|
153
279
|
const script = `\norigin = unreal.Vector(${ox}, ${oy}, ${oz})\nrot = unreal.Rotator(${rp}, ${ry}, ${rr})\ncolor = unreal.LinearColor(${r}/255.0, ${g}/255.0, ${b}/255.0, ${a}/255.0)\nunreal.SystemLibrary.draw_debug_frustum(world, origin, rot, ${params.fov}, ${aspectRatio}, ${nearPlane}, ${farPlane}, color, ${duration})\n`;
|
|
154
|
-
return this.pyDraw(script
|
|
280
|
+
return this.pyDraw(script, {
|
|
281
|
+
action: 'debug_frustum',
|
|
282
|
+
params: {
|
|
283
|
+
origin: params.origin,
|
|
284
|
+
rotation: params.rotation,
|
|
285
|
+
fov: params.fov,
|
|
286
|
+
aspectRatio,
|
|
287
|
+
nearPlane,
|
|
288
|
+
farPlane,
|
|
289
|
+
color,
|
|
290
|
+
duration
|
|
291
|
+
}
|
|
292
|
+
});
|
|
155
293
|
}
|
|
156
294
|
async clearDebugDrawings() {
|
|
157
295
|
return this.bridge.executeConsoleCommand('FlushPersistentDebugLines');
|
|
@@ -165,9 +303,7 @@ unreal.SystemLibrary.draw_debug_sphere(world, center, ${params.radius}, ${segmen
|
|
|
165
303
|
else {
|
|
166
304
|
commands.push('show Collision 0');
|
|
167
305
|
}
|
|
168
|
-
|
|
169
|
-
await this.bridge.executeConsoleCommand(cmd);
|
|
170
|
-
}
|
|
306
|
+
await this.bridge.executeConsoleCommands(commands);
|
|
171
307
|
return { success: true, message: `Collision visualization ${params.enabled ? 'enabled' : 'disabled'}` };
|
|
172
308
|
}
|
|
173
309
|
async showBounds(params) {
|
package/dist/tools/editor.d.ts
CHANGED
|
@@ -42,12 +42,19 @@ export declare class EditorTools {
|
|
|
42
42
|
}>;
|
|
43
43
|
buildLighting(): Promise<{
|
|
44
44
|
success: boolean;
|
|
45
|
-
message:
|
|
45
|
+
message: string;
|
|
46
46
|
error?: undefined;
|
|
47
|
+
details?: undefined;
|
|
48
|
+
} | {
|
|
49
|
+
success: boolean;
|
|
50
|
+
error: string;
|
|
51
|
+
details: string | undefined;
|
|
52
|
+
message?: undefined;
|
|
47
53
|
} | {
|
|
48
54
|
success: boolean;
|
|
49
|
-
error:
|
|
55
|
+
error: string;
|
|
50
56
|
message?: undefined;
|
|
57
|
+
details?: undefined;
|
|
51
58
|
}>;
|
|
52
59
|
setViewportCamera(location?: {
|
|
53
60
|
x: number;
|
package/dist/tools/editor.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { toVec3Object, toRotObject } from '../utils/normalize.js';
|
|
2
|
+
import { bestEffortInterpretedText, coerceString, interpretStandardResult } from '../utils/result-helpers.js';
|
|
2
3
|
export class EditorTools {
|
|
3
4
|
bridge;
|
|
4
5
|
constructor(bridge) {
|
|
@@ -65,28 +66,13 @@ else:
|
|
|
65
66
|
print('RESULT:' + json.dumps({'success': False, 'error': 'LevelEditorSubsystem not available'}))
|
|
66
67
|
`.trim();
|
|
67
68
|
const resp = await this.bridge.executePython(pythonCmd);
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return { success: true, message: `PIE started (via ${method})` };
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
try {
|
|
80
|
-
// Fallback: handle non-JSON python dict-style output
|
|
81
|
-
const sanitized = m[1].replace(/'/g, '"').replace(/\bTrue\b/g, 'true').replace(/\bFalse\b/g, 'false');
|
|
82
|
-
const parsed = JSON.parse(sanitized);
|
|
83
|
-
if (parsed.success) {
|
|
84
|
-
const method = parsed.method || 'LevelEditorSubsystem';
|
|
85
|
-
return { success: true, message: `PIE started (via ${method})` };
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch { }
|
|
89
|
-
}
|
|
69
|
+
const interpreted = interpretStandardResult(resp, {
|
|
70
|
+
successMessage: 'PIE started',
|
|
71
|
+
failureMessage: 'Failed to start PIE'
|
|
72
|
+
});
|
|
73
|
+
if (interpreted.success) {
|
|
74
|
+
const method = coerceString(interpreted.payload.method) ?? 'LevelEditorSubsystem';
|
|
75
|
+
return { success: true, message: `PIE started (via ${method})` };
|
|
90
76
|
}
|
|
91
77
|
// If not verified, fall through to fallback
|
|
92
78
|
}
|
|
@@ -125,20 +111,18 @@ else:
|
|
|
125
111
|
print('RESULT:' + json.dumps({'success': False, 'error': 'LevelEditorSubsystem not available'}))
|
|
126
112
|
`.trim();
|
|
127
113
|
const resp = await this.bridge.executePython(pythonCmd);
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
return { success: true, message: `PIE stopped via ${method}` };
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch { }
|
|
114
|
+
const interpreted = interpretStandardResult(resp, {
|
|
115
|
+
successMessage: 'PIE stopped successfully',
|
|
116
|
+
failureMessage: 'Failed to stop PIE'
|
|
117
|
+
});
|
|
118
|
+
if (interpreted.success) {
|
|
119
|
+
const method = coerceString(interpreted.payload.method) ?? 'LevelEditorSubsystem';
|
|
120
|
+
return { success: true, message: `PIE stopped via ${method}` };
|
|
139
121
|
}
|
|
140
|
-
|
|
141
|
-
|
|
122
|
+
if (interpreted.error) {
|
|
123
|
+
return { success: false, error: interpreted.error };
|
|
124
|
+
}
|
|
125
|
+
return { success: false, error: 'Failed to stop PIE' };
|
|
142
126
|
}
|
|
143
127
|
catch {
|
|
144
128
|
// Fallback to console command
|
|
@@ -193,16 +177,18 @@ except Exception as e:
|
|
|
193
177
|
print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))
|
|
194
178
|
`.trim();
|
|
195
179
|
const resp = await this.bridge.executePython(py);
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
}
|
|
203
|
-
catch { }
|
|
180
|
+
const interpreted = interpretStandardResult(resp, {
|
|
181
|
+
successMessage: 'Lighting build started',
|
|
182
|
+
failureMessage: 'Failed to build lighting'
|
|
183
|
+
});
|
|
184
|
+
if (interpreted.success) {
|
|
185
|
+
return { success: true, message: interpreted.message };
|
|
204
186
|
}
|
|
205
|
-
return {
|
|
187
|
+
return {
|
|
188
|
+
success: false,
|
|
189
|
+
error: interpreted.error ?? 'Failed to build lighting',
|
|
190
|
+
details: bestEffortInterpretedText(interpreted)
|
|
191
|
+
};
|
|
206
192
|
}
|
|
207
193
|
catch (err) {
|
|
208
194
|
return { success: false, error: `Failed to build lighting: ${err}` };
|
package/dist/tools/foliage.d.ts
CHANGED
|
@@ -14,22 +14,32 @@ export declare class FoliageTools {
|
|
|
14
14
|
groundSlope?: number;
|
|
15
15
|
}): Promise<{
|
|
16
16
|
success: boolean;
|
|
17
|
-
error:
|
|
17
|
+
error: string;
|
|
18
|
+
note?: undefined;
|
|
19
|
+
created?: undefined;
|
|
20
|
+
exists?: undefined;
|
|
21
|
+
method?: undefined;
|
|
22
|
+
assetPath?: undefined;
|
|
23
|
+
usedMesh?: undefined;
|
|
24
|
+
message?: undefined;
|
|
25
|
+
} | {
|
|
26
|
+
success: boolean;
|
|
27
|
+
error: string;
|
|
28
|
+
note: string | undefined;
|
|
18
29
|
created?: undefined;
|
|
19
30
|
exists?: undefined;
|
|
20
31
|
method?: undefined;
|
|
21
32
|
assetPath?: undefined;
|
|
22
33
|
usedMesh?: undefined;
|
|
23
|
-
note?: undefined;
|
|
24
34
|
message?: undefined;
|
|
25
35
|
} | {
|
|
26
36
|
success: boolean;
|
|
27
|
-
created:
|
|
28
|
-
exists:
|
|
29
|
-
method:
|
|
30
|
-
assetPath:
|
|
31
|
-
usedMesh:
|
|
32
|
-
note:
|
|
37
|
+
created: boolean;
|
|
38
|
+
exists: boolean;
|
|
39
|
+
method: string;
|
|
40
|
+
assetPath: string | undefined;
|
|
41
|
+
usedMesh: string | undefined;
|
|
42
|
+
note: string | undefined;
|
|
33
43
|
message: string;
|
|
34
44
|
error?: undefined;
|
|
35
45
|
}>;
|
|
@@ -41,20 +51,29 @@ export declare class FoliageTools {
|
|
|
41
51
|
eraseMode?: boolean;
|
|
42
52
|
}): Promise<{
|
|
43
53
|
success: boolean;
|
|
44
|
-
error:
|
|
54
|
+
error: string;
|
|
55
|
+
note?: undefined;
|
|
56
|
+
added?: undefined;
|
|
57
|
+
actor?: undefined;
|
|
58
|
+
component?: undefined;
|
|
59
|
+
usedMesh?: undefined;
|
|
60
|
+
message?: undefined;
|
|
61
|
+
} | {
|
|
62
|
+
success: boolean;
|
|
63
|
+
error: string;
|
|
64
|
+
note: string | undefined;
|
|
45
65
|
added?: undefined;
|
|
46
66
|
actor?: undefined;
|
|
47
67
|
component?: undefined;
|
|
48
68
|
usedMesh?: undefined;
|
|
49
|
-
note?: undefined;
|
|
50
69
|
message?: undefined;
|
|
51
70
|
} | {
|
|
52
71
|
success: boolean;
|
|
53
|
-
added:
|
|
54
|
-
actor:
|
|
55
|
-
component:
|
|
56
|
-
usedMesh:
|
|
57
|
-
note:
|
|
72
|
+
added: number;
|
|
73
|
+
actor: string | undefined;
|
|
74
|
+
component: string | undefined;
|
|
75
|
+
usedMesh: string | undefined;
|
|
76
|
+
note: string | undefined;
|
|
58
77
|
message: string;
|
|
59
78
|
error?: undefined;
|
|
60
79
|
}>;
|