unreal-engine-mcp-server 0.4.0 → 0.4.4

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.
Files changed (135) hide show
  1. package/.env.production +1 -1
  2. package/.github/copilot-instructions.md +45 -0
  3. package/.github/workflows/publish-mcp.yml +3 -2
  4. package/README.md +21 -5
  5. package/dist/index.js +124 -31
  6. package/dist/prompts/index.d.ts +10 -3
  7. package/dist/prompts/index.js +186 -7
  8. package/dist/resources/actors.d.ts +19 -1
  9. package/dist/resources/actors.js +55 -64
  10. package/dist/resources/assets.js +46 -62
  11. package/dist/resources/levels.d.ts +21 -3
  12. package/dist/resources/levels.js +29 -54
  13. package/dist/tools/actors.d.ts +3 -14
  14. package/dist/tools/actors.js +246 -302
  15. package/dist/tools/animation.d.ts +57 -102
  16. package/dist/tools/animation.js +429 -450
  17. package/dist/tools/assets.d.ts +13 -2
  18. package/dist/tools/assets.js +52 -44
  19. package/dist/tools/audio.d.ts +22 -13
  20. package/dist/tools/audio.js +467 -121
  21. package/dist/tools/blueprint.d.ts +32 -13
  22. package/dist/tools/blueprint.js +699 -448
  23. package/dist/tools/build_environment_advanced.d.ts +0 -1
  24. package/dist/tools/build_environment_advanced.js +190 -45
  25. package/dist/tools/consolidated-tool-definitions.js +78 -252
  26. package/dist/tools/consolidated-tool-handlers.js +506 -133
  27. package/dist/tools/debug.d.ts +72 -10
  28. package/dist/tools/debug.js +167 -31
  29. package/dist/tools/editor.d.ts +9 -2
  30. package/dist/tools/editor.js +30 -44
  31. package/dist/tools/foliage.d.ts +34 -15
  32. package/dist/tools/foliage.js +97 -107
  33. package/dist/tools/introspection.js +19 -21
  34. package/dist/tools/landscape.d.ts +1 -2
  35. package/dist/tools/landscape.js +311 -168
  36. package/dist/tools/level.d.ts +3 -28
  37. package/dist/tools/level.js +642 -192
  38. package/dist/tools/lighting.d.ts +14 -3
  39. package/dist/tools/lighting.js +236 -123
  40. package/dist/tools/materials.d.ts +25 -7
  41. package/dist/tools/materials.js +102 -79
  42. package/dist/tools/niagara.d.ts +10 -12
  43. package/dist/tools/niagara.js +74 -94
  44. package/dist/tools/performance.d.ts +12 -4
  45. package/dist/tools/performance.js +38 -79
  46. package/dist/tools/physics.d.ts +34 -10
  47. package/dist/tools/physics.js +364 -292
  48. package/dist/tools/rc.js +97 -23
  49. package/dist/tools/sequence.d.ts +1 -0
  50. package/dist/tools/sequence.js +125 -22
  51. package/dist/tools/ui.d.ts +31 -4
  52. package/dist/tools/ui.js +83 -66
  53. package/dist/tools/visual.d.ts +11 -0
  54. package/dist/tools/visual.js +245 -30
  55. package/dist/types/tool-types.d.ts +0 -6
  56. package/dist/types/tool-types.js +1 -8
  57. package/dist/unreal-bridge.d.ts +32 -2
  58. package/dist/unreal-bridge.js +621 -127
  59. package/dist/utils/elicitation.d.ts +57 -0
  60. package/dist/utils/elicitation.js +104 -0
  61. package/dist/utils/error-handler.d.ts +0 -33
  62. package/dist/utils/error-handler.js +4 -111
  63. package/dist/utils/http.d.ts +2 -22
  64. package/dist/utils/http.js +12 -75
  65. package/dist/utils/normalize.d.ts +4 -4
  66. package/dist/utils/normalize.js +15 -7
  67. package/dist/utils/python-output.d.ts +18 -0
  68. package/dist/utils/python-output.js +290 -0
  69. package/dist/utils/python.d.ts +2 -0
  70. package/dist/utils/python.js +4 -0
  71. package/dist/utils/response-validator.js +28 -2
  72. package/dist/utils/result-helpers.d.ts +27 -0
  73. package/dist/utils/result-helpers.js +147 -0
  74. package/dist/utils/safe-json.d.ts +0 -2
  75. package/dist/utils/safe-json.js +0 -43
  76. package/dist/utils/validation.d.ts +16 -0
  77. package/dist/utils/validation.js +70 -7
  78. package/mcp-config-example.json +2 -2
  79. package/package.json +10 -9
  80. package/server.json +37 -14
  81. package/src/index.ts +130 -33
  82. package/src/prompts/index.ts +211 -13
  83. package/src/resources/actors.ts +59 -44
  84. package/src/resources/assets.ts +48 -51
  85. package/src/resources/levels.ts +35 -45
  86. package/src/tools/actors.ts +269 -313
  87. package/src/tools/animation.ts +556 -539
  88. package/src/tools/assets.ts +53 -43
  89. package/src/tools/audio.ts +507 -113
  90. package/src/tools/blueprint.ts +778 -462
  91. package/src/tools/build_environment_advanced.ts +266 -64
  92. package/src/tools/consolidated-tool-definitions.ts +90 -264
  93. package/src/tools/consolidated-tool-handlers.ts +630 -121
  94. package/src/tools/debug.ts +176 -33
  95. package/src/tools/editor.ts +35 -37
  96. package/src/tools/foliage.ts +110 -104
  97. package/src/tools/introspection.ts +24 -22
  98. package/src/tools/landscape.ts +334 -181
  99. package/src/tools/level.ts +683 -182
  100. package/src/tools/lighting.ts +244 -123
  101. package/src/tools/materials.ts +114 -83
  102. package/src/tools/niagara.ts +87 -81
  103. package/src/tools/performance.ts +49 -88
  104. package/src/tools/physics.ts +393 -299
  105. package/src/tools/rc.ts +102 -24
  106. package/src/tools/sequence.ts +136 -28
  107. package/src/tools/ui.ts +101 -70
  108. package/src/tools/visual.ts +250 -29
  109. package/src/types/tool-types.ts +0 -9
  110. package/src/unreal-bridge.ts +658 -140
  111. package/src/utils/elicitation.ts +129 -0
  112. package/src/utils/error-handler.ts +4 -159
  113. package/src/utils/http.ts +16 -115
  114. package/src/utils/normalize.ts +20 -10
  115. package/src/utils/python-output.ts +351 -0
  116. package/src/utils/python.ts +3 -0
  117. package/src/utils/response-validator.ts +25 -2
  118. package/src/utils/result-helpers.ts +193 -0
  119. package/src/utils/safe-json.ts +0 -50
  120. package/src/utils/validation.ts +94 -7
  121. package/tests/run-unreal-tool-tests.mjs +720 -0
  122. package/tsconfig.json +2 -2
  123. package/dist/python-utils.d.ts +0 -29
  124. package/dist/python-utils.js +0 -54
  125. package/dist/types/index.d.ts +0 -323
  126. package/dist/types/index.js +0 -28
  127. package/dist/utils/cache-manager.d.ts +0 -64
  128. package/dist/utils/cache-manager.js +0 -176
  129. package/dist/utils/errors.d.ts +0 -133
  130. package/dist/utils/errors.js +0 -256
  131. package/src/python/editor_compat.py +0 -181
  132. package/src/python-utils.ts +0 -57
  133. package/src/types/index.ts +0 -414
  134. package/src/utils/cache-manager.ts +0 -213
  135. package/src/utils/errors.ts +0 -312
@@ -1,133 +0,0 @@
1
- /**
2
- * Enhanced error types for better error handling and recovery
3
- */
4
- export declare enum ErrorCode {
5
- CONNECTION_FAILED = "CONNECTION_FAILED",
6
- CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT",
7
- CONNECTION_REFUSED = "CONNECTION_REFUSED",
8
- API_ERROR = "API_ERROR",
9
- INVALID_RESPONSE = "INVALID_RESPONSE",
10
- RATE_LIMITED = "RATE_LIMITED",
11
- VALIDATION_ERROR = "VALIDATION_ERROR",
12
- INVALID_PARAMETERS = "INVALID_PARAMETERS",
13
- MISSING_REQUIRED_FIELD = "MISSING_REQUIRED_FIELD",
14
- RESOURCE_NOT_FOUND = "RESOURCE_NOT_FOUND",
15
- RESOURCE_LOCKED = "RESOURCE_LOCKED",
16
- RESOURCE_UNAVAILABLE = "RESOURCE_UNAVAILABLE",
17
- UNAUTHORIZED = "UNAUTHORIZED",
18
- FORBIDDEN = "FORBIDDEN",
19
- INTERNAL_ERROR = "INTERNAL_ERROR",
20
- CIRCUIT_BREAKER_OPEN = "CIRCUIT_BREAKER_OPEN",
21
- SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
22
- }
23
- export interface ErrorMetadata {
24
- code: ErrorCode;
25
- statusCode?: number;
26
- retriable: boolean;
27
- context?: Record<string, any>;
28
- timestamp: Date;
29
- correlationId?: string;
30
- }
31
- /**
32
- * Base application error with metadata
33
- */
34
- export declare class AppError extends Error {
35
- readonly metadata: ErrorMetadata;
36
- constructor(message: string, metadata?: Partial<ErrorMetadata>);
37
- toJSON(): {
38
- stack: string | undefined;
39
- code: ErrorCode;
40
- statusCode?: number;
41
- retriable: boolean;
42
- context?: Record<string, any>;
43
- timestamp: Date;
44
- correlationId?: string;
45
- name: string;
46
- message: string;
47
- };
48
- }
49
- /**
50
- * Connection-related errors
51
- */
52
- export declare class ConnectionError extends AppError {
53
- constructor(message: string, metadata?: Partial<ErrorMetadata>);
54
- }
55
- /**
56
- * API-related errors
57
- */
58
- export declare class ApiError extends AppError {
59
- constructor(message: string, statusCode: number, metadata?: Partial<ErrorMetadata>);
60
- }
61
- /**
62
- * Validation errors
63
- */
64
- export declare class ValidationError extends AppError {
65
- constructor(message: string, metadata?: Partial<ErrorMetadata>);
66
- }
67
- /**
68
- * Resource errors
69
- */
70
- export declare class ResourceError extends AppError {
71
- constructor(message: string, code: ErrorCode, metadata?: Partial<ErrorMetadata>);
72
- }
73
- /**
74
- * Circuit Breaker implementation for fault tolerance
75
- */
76
- export declare enum CircuitState {
77
- CLOSED = "CLOSED",
78
- OPEN = "OPEN",
79
- HALF_OPEN = "HALF_OPEN"
80
- }
81
- interface CircuitBreakerOptions {
82
- threshold: number;
83
- timeout: number;
84
- resetTimeout: number;
85
- onStateChange?: (oldState: CircuitState, newState: CircuitState) => void;
86
- }
87
- export declare class CircuitBreaker {
88
- private state;
89
- private failures;
90
- private successCount;
91
- private lastFailureTime?;
92
- private readonly options;
93
- constructor(options?: Partial<CircuitBreakerOptions>);
94
- /**
95
- * Execute function with circuit breaker protection
96
- */
97
- execute<T>(fn: () => Promise<T>): Promise<T>;
98
- private onSuccess;
99
- private onFailure;
100
- private shouldAttemptReset;
101
- private transitionTo;
102
- getState(): CircuitState;
103
- getMetrics(): {
104
- state: CircuitState;
105
- failures: number;
106
- successCount: number;
107
- lastFailureTime: Date | undefined;
108
- };
109
- }
110
- /**
111
- * Error recovery strategies
112
- */
113
- export declare class ErrorRecovery {
114
- private static circuitBreakers;
115
- /**
116
- * Get or create circuit breaker for a service
117
- */
118
- static getCircuitBreaker(service: string, options?: Partial<CircuitBreakerOptions>): CircuitBreaker;
119
- /**
120
- * Wrap function with error recovery
121
- */
122
- static withRecovery<T>(fn: () => Promise<T>, options: {
123
- service: string;
124
- fallback?: () => T | Promise<T>;
125
- onError?: (error: Error) => void;
126
- }): Promise<T>;
127
- /**
128
- * Check if error is retriable
129
- */
130
- static isRetriable(error: Error): boolean;
131
- }
132
- export {};
133
- //# sourceMappingURL=errors.d.ts.map
@@ -1,256 +0,0 @@
1
- /**
2
- * Enhanced error types for better error handling and recovery
3
- */
4
- export var ErrorCode;
5
- (function (ErrorCode) {
6
- // Connection errors
7
- ErrorCode["CONNECTION_FAILED"] = "CONNECTION_FAILED";
8
- ErrorCode["CONNECTION_TIMEOUT"] = "CONNECTION_TIMEOUT";
9
- ErrorCode["CONNECTION_REFUSED"] = "CONNECTION_REFUSED";
10
- // API errors
11
- ErrorCode["API_ERROR"] = "API_ERROR";
12
- ErrorCode["INVALID_RESPONSE"] = "INVALID_RESPONSE";
13
- ErrorCode["RATE_LIMITED"] = "RATE_LIMITED";
14
- // Validation errors
15
- ErrorCode["VALIDATION_ERROR"] = "VALIDATION_ERROR";
16
- ErrorCode["INVALID_PARAMETERS"] = "INVALID_PARAMETERS";
17
- ErrorCode["MISSING_REQUIRED_FIELD"] = "MISSING_REQUIRED_FIELD";
18
- // Resource errors
19
- ErrorCode["RESOURCE_NOT_FOUND"] = "RESOURCE_NOT_FOUND";
20
- ErrorCode["RESOURCE_LOCKED"] = "RESOURCE_LOCKED";
21
- ErrorCode["RESOURCE_UNAVAILABLE"] = "RESOURCE_UNAVAILABLE";
22
- // Permission errors
23
- ErrorCode["UNAUTHORIZED"] = "UNAUTHORIZED";
24
- ErrorCode["FORBIDDEN"] = "FORBIDDEN";
25
- // System errors
26
- ErrorCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
27
- ErrorCode["CIRCUIT_BREAKER_OPEN"] = "CIRCUIT_BREAKER_OPEN";
28
- ErrorCode["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
29
- })(ErrorCode || (ErrorCode = {}));
30
- /**
31
- * Base application error with metadata
32
- */
33
- export class AppError extends Error {
34
- metadata;
35
- constructor(message, metadata = {}) {
36
- super(message);
37
- this.name = this.constructor.name;
38
- this.metadata = {
39
- code: metadata.code || ErrorCode.INTERNAL_ERROR,
40
- retriable: metadata.retriable || false,
41
- timestamp: new Date(),
42
- ...metadata
43
- };
44
- Error.captureStackTrace(this, this.constructor);
45
- }
46
- toJSON() {
47
- return {
48
- name: this.name,
49
- message: this.message,
50
- ...this.metadata,
51
- stack: this.stack
52
- };
53
- }
54
- }
55
- /**
56
- * Connection-related errors
57
- */
58
- export class ConnectionError extends AppError {
59
- constructor(message, metadata = {}) {
60
- super(message, {
61
- code: ErrorCode.CONNECTION_FAILED,
62
- retriable: true,
63
- statusCode: 503,
64
- ...metadata
65
- });
66
- }
67
- }
68
- /**
69
- * API-related errors
70
- */
71
- export class ApiError extends AppError {
72
- constructor(message, statusCode, metadata = {}) {
73
- super(message, {
74
- code: ErrorCode.API_ERROR,
75
- statusCode,
76
- retriable: statusCode >= 500 || statusCode === 429,
77
- ...metadata
78
- });
79
- }
80
- }
81
- /**
82
- * Validation errors
83
- */
84
- export class ValidationError extends AppError {
85
- constructor(message, metadata = {}) {
86
- super(message, {
87
- code: ErrorCode.VALIDATION_ERROR,
88
- statusCode: 400,
89
- retriable: false,
90
- ...metadata
91
- });
92
- }
93
- }
94
- /**
95
- * Resource errors
96
- */
97
- export class ResourceError extends AppError {
98
- constructor(message, code, metadata = {}) {
99
- super(message, {
100
- code,
101
- statusCode: code === ErrorCode.RESOURCE_NOT_FOUND ? 404 : 409,
102
- retriable: code === ErrorCode.RESOURCE_LOCKED,
103
- ...metadata
104
- });
105
- }
106
- }
107
- /**
108
- * Circuit Breaker implementation for fault tolerance
109
- */
110
- export var CircuitState;
111
- (function (CircuitState) {
112
- CircuitState["CLOSED"] = "CLOSED";
113
- CircuitState["OPEN"] = "OPEN";
114
- CircuitState["HALF_OPEN"] = "HALF_OPEN";
115
- })(CircuitState || (CircuitState = {}));
116
- export class CircuitBreaker {
117
- state = CircuitState.CLOSED;
118
- failures = 0;
119
- successCount = 0;
120
- lastFailureTime;
121
- options;
122
- constructor(options = {}) {
123
- this.options = {
124
- threshold: options.threshold || 5,
125
- timeout: options.timeout || 60000, // 1 minute
126
- resetTimeout: options.resetTimeout || 30000, // 30 seconds
127
- onStateChange: options.onStateChange
128
- };
129
- }
130
- /**
131
- * Execute function with circuit breaker protection
132
- */
133
- async execute(fn) {
134
- // Check circuit state
135
- if (this.state === CircuitState.OPEN) {
136
- if (this.shouldAttemptReset()) {
137
- this.transitionTo(CircuitState.HALF_OPEN);
138
- }
139
- else {
140
- throw new AppError('Circuit breaker is open', {
141
- code: ErrorCode.CIRCUIT_BREAKER_OPEN,
142
- retriable: true,
143
- context: {
144
- failures: this.failures,
145
- lastFailure: this.lastFailureTime
146
- }
147
- });
148
- }
149
- }
150
- try {
151
- const result = await fn();
152
- this.onSuccess();
153
- return result;
154
- }
155
- catch (error) {
156
- this.onFailure();
157
- throw error;
158
- }
159
- }
160
- onSuccess() {
161
- this.failures = 0;
162
- if (this.state === CircuitState.HALF_OPEN) {
163
- this.successCount++;
164
- if (this.successCount >= 3) {
165
- this.transitionTo(CircuitState.CLOSED);
166
- }
167
- }
168
- }
169
- onFailure() {
170
- this.failures++;
171
- this.lastFailureTime = new Date();
172
- this.successCount = 0;
173
- if (this.failures >= this.options.threshold) {
174
- this.transitionTo(CircuitState.OPEN);
175
- }
176
- }
177
- shouldAttemptReset() {
178
- return (this.lastFailureTime !== undefined &&
179
- Date.now() - this.lastFailureTime.getTime() >= this.options.resetTimeout);
180
- }
181
- transitionTo(newState) {
182
- const oldState = this.state;
183
- this.state = newState;
184
- if (newState === CircuitState.CLOSED) {
185
- this.failures = 0;
186
- this.successCount = 0;
187
- }
188
- if (this.options.onStateChange && oldState !== newState) {
189
- this.options.onStateChange(oldState, newState);
190
- }
191
- }
192
- getState() {
193
- return this.state;
194
- }
195
- getMetrics() {
196
- return {
197
- state: this.state,
198
- failures: this.failures,
199
- successCount: this.successCount,
200
- lastFailureTime: this.lastFailureTime
201
- };
202
- }
203
- }
204
- /**
205
- * Error recovery strategies
206
- */
207
- export class ErrorRecovery {
208
- static circuitBreakers = new Map();
209
- /**
210
- * Get or create circuit breaker for a service
211
- */
212
- static getCircuitBreaker(service, options) {
213
- if (!this.circuitBreakers.has(service)) {
214
- this.circuitBreakers.set(service, new CircuitBreaker(options));
215
- }
216
- const breaker = this.circuitBreakers.get(service);
217
- if (!breaker) {
218
- throw new Error(`Circuit breaker for service ${service} could not be created`);
219
- }
220
- return breaker;
221
- }
222
- /**
223
- * Wrap function with error recovery
224
- */
225
- static async withRecovery(fn, options) {
226
- const breaker = this.getCircuitBreaker(options.service);
227
- try {
228
- return await breaker.execute(fn);
229
- }
230
- catch (error) {
231
- if (options.onError) {
232
- options.onError(error);
233
- }
234
- // Try fallback if available
235
- if (options.fallback) {
236
- return await options.fallback();
237
- }
238
- throw error;
239
- }
240
- }
241
- /**
242
- * Check if error is retriable
243
- */
244
- static isRetriable(error) {
245
- if (error instanceof AppError) {
246
- return error.metadata.retriable;
247
- }
248
- // Check for network errors
249
- const message = error.message.toLowerCase();
250
- return (message.includes('timeout') ||
251
- message.includes('network') ||
252
- message.includes('econnrefused') ||
253
- message.includes('econnreset'));
254
- }
255
- }
256
- //# sourceMappingURL=errors.js.map
@@ -1,181 +0,0 @@
1
- """
2
- Compatibility module for handling deprecated Unreal Engine Python API calls.
3
- Provides wrapper functions that use the newer recommended APIs where available.
4
- """
5
-
6
- import unreal
7
-
8
- def get_editor_world():
9
- """
10
- Get the current editor world using the recommended API.
11
- """
12
- try:
13
- # Use new recommended API
14
- if hasattr(unreal, 'UnrealEditorSubsystem'):
15
- subsystem = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
16
- if hasattr(subsystem, 'get_editor_world'):
17
- return subsystem.get_editor_world()
18
- except:
19
- pass
20
-
21
- return None
22
-
23
- def get_all_level_actors():
24
- """
25
- Get all actors in the current level using the recommended API.
26
- """
27
- try:
28
- # Use new recommended API - EditorActorSubsystem
29
- if hasattr(unreal, 'EditorActorSubsystem'):
30
- subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
31
- if hasattr(subsystem, 'get_all_level_actors'):
32
- return subsystem.get_all_level_actors()
33
- except:
34
- pass
35
-
36
- return []
37
-
38
- def spawn_actor_from_class(actor_class, location, rotation):
39
- """
40
- Spawn an actor in the level using the recommended API.
41
- """
42
- try:
43
- # Use new recommended API
44
- if hasattr(unreal, 'EditorActorSubsystem'):
45
- subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
46
- if hasattr(subsystem, 'spawn_actor_from_class'):
47
- return subsystem.spawn_actor_from_class(actor_class, location, rotation)
48
- except:
49
- pass
50
-
51
- return None
52
-
53
- def destroy_actor(actor):
54
- """
55
- Destroy an actor in the level using the recommended API.
56
- """
57
- try:
58
- # Use new recommended API
59
- if hasattr(unreal, 'EditorActorSubsystem'):
60
- subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
61
- if hasattr(subsystem, 'destroy_actor'):
62
- return subsystem.destroy_actor(actor)
63
- except:
64
- pass
65
-
66
- return False
67
-
68
- def save_current_level():
69
- """
70
- Save the current level using the recommended API.
71
- """
72
- try:
73
- # Use new recommended API - LevelEditorSubsystem
74
- if hasattr(unreal, 'LevelEditorSubsystem'):
75
- subsystem = unreal.get_editor_subsystem(unreal.LevelEditorSubsystem)
76
- if hasattr(subsystem, 'save_current_level'):
77
- return subsystem.save_current_level()
78
- except:
79
- pass
80
-
81
- return False
82
-
83
- def get_level_viewport_camera_info():
84
- """
85
- Get level viewport camera information using the recommended API.
86
- """
87
- try:
88
- # Use new recommended API
89
- if hasattr(unreal, 'UnrealEditorSubsystem'):
90
- subsystem = unreal.get_editor_subsystem(unreal.UnrealEditorSubsystem)
91
- if hasattr(subsystem, 'get_level_viewport_camera_info'):
92
- return subsystem.get_level_viewport_camera_info()
93
- except:
94
- pass
95
-
96
- return None
97
-
98
- # Blueprint compatibility functions
99
- def get_blueprint_generated_class(blueprint):
100
- """
101
- Get the generated class from a blueprint using the recommended API.
102
- """
103
- try:
104
- # Try using BlueprintEditorLibrary
105
- if hasattr(unreal, 'BlueprintEditorLibrary'):
106
- return unreal.BlueprintEditorLibrary.generated_class(blueprint)
107
- except:
108
- pass
109
-
110
- # Try getting it as a property (might not work)
111
- try:
112
- return blueprint.get_editor_property('generated_class')
113
- except:
114
- pass
115
-
116
- return None
117
-
118
- def get_blueprint_parent_class(blueprint):
119
- """
120
- Get the parent class from a blueprint.
121
- """
122
- try:
123
- # Try getting it as a property
124
- return blueprint.get_editor_property('parent_class')
125
- except:
126
- pass
127
-
128
- # Default to Actor for most blueprints
129
- return unreal.Actor if hasattr(unreal, 'Actor') else None
130
-
131
- def get_class_name(unreal_class):
132
- """
133
- Get the name of an Unreal class object safely.
134
- """
135
- if not unreal_class:
136
- return "None"
137
-
138
- # Try various methods to get the class name
139
- try:
140
- if hasattr(unreal_class, '__name__'):
141
- return unreal_class.__name__
142
- except:
143
- pass
144
-
145
- try:
146
- if hasattr(unreal_class, 'get_name'):
147
- # get_name() is a method on instances, not classes
148
- # So we need to be careful here
149
- return str(unreal_class).split('.')[-1].replace("'", "").replace('>', '')
150
- except:
151
- pass
152
-
153
- # Fallback to string representation
154
- class_str = str(unreal_class)
155
- if '.' in class_str:
156
- return class_str.split('.')[-1].replace("'", "").replace('>', '')
157
-
158
- return class_str
159
-
160
- def ensure_kismet_system_library():
161
- """
162
- Try to import KismetSystemLibrary if available.
163
- Note: This library might not be available in all UE versions or configurations.
164
- """
165
- try:
166
- # KismetSystemLibrary is part of the BlueprintGraph module
167
- # It might not be exposed to Python in all versions
168
- if hasattr(unreal, 'KismetSystemLibrary'):
169
- return unreal.KismetSystemLibrary
170
-
171
- # Try alternate import methods
172
- import importlib
173
- try:
174
- kismet = importlib.import_module('unreal.KismetSystemLibrary')
175
- return kismet
176
- except:
177
- pass
178
- except:
179
- pass
180
-
181
- return None
@@ -1,57 +0,0 @@
1
- /**
2
- * Python Utilities for Modern Unreal Engine API
3
- *
4
- * This module provides Python code snippets that use the modern
5
- * Unreal Engine Python API instead of deprecated functions.
6
- */
7
-
8
- export class PythonUtils {
9
- /**
10
- * Get all actors in the level using modern API
11
- * @returns Python code to get all level actors
12
- */
13
- static getAllLevelActors(): string {
14
- return `
15
- # Use modern EditorActorSubsystem instead of deprecated EditorLevelLibrary
16
- editor_actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
17
- actors = editor_actor_subsystem.get_all_level_actors()
18
- `.trim();
19
- }
20
-
21
- /**
22
- * Get selected actors using modern API
23
- * @returns Python code to get selected actors
24
- */
25
- static getSelectedActors(): string {
26
- return `
27
- editor_actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
28
- selected_actors = editor_actor_subsystem.get_selected_level_actors()
29
- `.trim();
30
- }
31
-
32
- /**
33
- * Spawn actor from class using modern API
34
- * @returns Python code to spawn actor
35
- */
36
- static spawnActorFromClass(): string {
37
- return `
38
- editor_actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
39
- # Use spawn_actor_from_class for spawning
40
- `.trim();
41
- }
42
-
43
- /**
44
- * Get a safe way to access actors
45
- * @returns Python code with modern API
46
- */
47
- static getSafeActorAccess(): string {
48
- return `
49
- # Use modern API
50
- try:
51
- editor_actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
52
- actors = editor_actor_subsystem.get_all_level_actors() if editor_actor_subsystem else []
53
- except:
54
- actors = []
55
- `.trim();
56
- }
57
- }