1
2
3"""
4Unity AI Assistant Apify Actor
5
6Provides AI-powered Unity development tools as an Apify Actor.
7Supports script generation, shader creation, LLM queries, and Unity Cloud Services.
8"""
9
10import os
11import asyncio
12from typing import Dict, Any, Optional
13from apify import Actor
14
15
16import sys
17sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
18
19from unity_ai_assistant import UnityAIAssistantServer
20from unity_llm_bridge import UnityLLMBridgeServer
21from eden_ai_unity import EdenAIUnityServer
22from unity_cloud_services import UnityCloudServicesServer
23from common.unity_types import UnityContext, UnityVersion, UnityPlatform
24
25
26async def main() -> None:
27 """Main Actor entry point."""
28 async with Actor:
29
30 actor_input = await Actor.get_input() or {}
31
32 Actor.log.info(f"Actor started with operation: {actor_input.get('operation')}")
33
34
35 if actor_input.get('openaiApiKey'):
36 os.environ['OPENAI_API_KEY'] = actor_input['openaiApiKey']
37 if actor_input.get('anthropicApiKey'):
38 os.environ['ANTHROPIC_API_KEY'] = actor_input['anthropicApiKey']
39 if actor_input.get('googleApiKey'):
40 os.environ['GOOGLE_API_KEY'] = actor_input['googleApiKey']
41 if actor_input.get('unityProjectId'):
42 os.environ['UNITY_PROJECT_ID'] = actor_input['unityProjectId']
43
44
45 platform_map = {
46 'Windows': UnityPlatform.WINDOWS,
47 'macOS': UnityPlatform.MACOS,
48 'Linux': UnityPlatform.LINUX,
49 'Android': UnityPlatform.ANDROID,
50 'iOS': UnityPlatform.IOS,
51 'WebGL': UnityPlatform.WEBGL,
52 }
53
54 unity_context = UnityContext(
55 project_id=actor_input.get('unityProjectId'),
56 target_platform=platform_map.get(actor_input.get('targetPlatform', 'Windows'), UnityPlatform.WINDOWS)
57 )
58
59
60 operation = actor_input.get('operation')
61 result = {}
62
63 try:
64 if operation == 'generate_script':
65 result = await generate_script(actor_input, unity_context)
66
67 elif operation == 'create_shader':
68 result = await create_shader(actor_input, unity_context)
69
70 elif operation == 'analyze_gameobject':
71 result = await analyze_gameobject(actor_input, unity_context)
72
73 elif operation == 'optimize_prefab':
74 result = await optimize_prefab(actor_input, unity_context)
75
76 elif operation == 'query_llm':
77 result = await query_llm(actor_input, unity_context)
78
79 elif operation == 'code_completion':
80 result = await code_completion(actor_input, unity_context)
81
82 elif operation == 'analyze_code':
83 result = await analyze_code(actor_input, unity_context)
84
85 elif operation == 'text_to_speech':
86 result = await text_to_speech(actor_input, unity_context)
87
88 elif operation == 'npc_dialogue':
89 result = await npc_dialogue(actor_input, unity_context)
90
91 elif operation == 'translate_ui':
92 result = await translate_ui(actor_input, unity_context)
93
94 elif operation == 'vision_analysis':
95 result = await vision_analysis(actor_input, unity_context)
96
97 elif operation == 'deploy_cloud_code':
98 result = await deploy_cloud_code(actor_input, unity_context)
99
100 elif operation == 'manage_remote_config':
101 result = await manage_remote_config(actor_input, unity_context)
102
103 elif operation == 'query_analytics':
104 result = await query_analytics(actor_input, unity_context)
105
106 else:
107 result = {
108 'success': False,
109 'error': f'Unknown operation: {operation}'
110 }
111
112
113 await Actor.push_data({
114 'operation': operation,
115 'success': result.get('success', True),
116 'result': result,
117 'input': actor_input
118 })
119
120 Actor.log.info(f"Operation completed successfully: {operation}")
121
122 except Exception as e:
123 Actor.log.exception(f"Error during operation {operation}")
124 await Actor.push_data({
125 'operation': operation,
126 'success': False,
127 'error': str(e),
128 'input': actor_input
129 })
130
131
132async def generate_script(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
133 """Generate Unity C# script."""
134 server = UnityAIAssistantServer()
135 server.set_unity_context(context)
136 await server.initialize()
137
138 try:
139 result = await server.call_tool('generate_unity_script', {
140 'description': input_data.get('scriptDescription', ''),
141 'script_name': input_data.get('scriptName', 'GeneratedScript'),
142 'base_class': 'MonoBehaviour',
143 'target_platform': context.target_platform,
144 })
145 return result.get('result', result)
146 finally:
147 await server.shutdown()
148
149
150async def create_shader(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
151 """Create Unity shader."""
152 server = UnityAIAssistantServer()
153 server.set_unity_context(context)
154 await server.initialize()
155
156 try:
157 result = await server.call_tool('create_shader_code', {
158 'shader_name': input_data.get('shaderName', 'CustomShader'),
159 'shader_type': input_data.get('shaderType', 'Lit'),
160 'render_pipeline': input_data.get('renderPipeline', 'URP'),
161 'description': input_data.get('scriptDescription', 'Custom shader'),
162 'features': []
163 })
164 return result.get('result', result)
165 finally:
166 await server.shutdown()
167
168
169async def analyze_gameobject(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
170 """Analyze GameObject."""
171 server = UnityAIAssistantServer()
172 server.set_unity_context(context)
173 await server.initialize()
174
175 try:
176 result = await server.call_tool('analyze_gameobject', {
177 'gameobject_name': input_data.get('gameObjectName', 'GameObject'),
178 'include_children': True,
179 'analyze_components': True
180 })
181 return result.get('result', result)
182 finally:
183 await server.shutdown()
184
185
186async def optimize_prefab(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
187 """Optimize prefab."""
188 server = UnityAIAssistantServer()
189 server.set_unity_context(context)
190 await server.initialize()
191
192 try:
193 result = await server.call_tool('suggest_prefab_optimization', {
194 'prefab_name': input_data.get('prefabName', 'Prefab'),
195 'target_platform': context.target_platform,
196 'optimization_level': 'high'
197 })
198 return result.get('result', result)
199 finally:
200 await server.shutdown()
201
202
203async def query_llm(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
204 """Query external LLM."""
205 server = UnityLLMBridgeServer()
206 server.set_unity_context(context)
207 await server.initialize()
208
209 try:
210 result = await server.call_tool('query_external_llm', {
211 'model': input_data.get('llmModel', 'gpt-4'),
212 'prompt': input_data.get('llmPrompt', ''),
213 'unity_context': context.dict(),
214 'response_format': 'narrative',
215 'temperature': 0.7
216 })
217 return result.get('result', result)
218 finally:
219 await server.shutdown()
220
221
222async def code_completion(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
223 """Generate code completion."""
224 server = UnityLLMBridgeServer()
225 server.set_unity_context(context)
226 await server.initialize()
227
228 try:
229 code = input_data.get('codeToAnalyze', '')
230 result = await server.call_tool('generate_code_completion', {
231 'code_context': code,
232 'cursor_position': len(code),
233 'language': 'csharp'
234 })
235 return result.get('result', result)
236 finally:
237 await server.shutdown()
238
239
240async def analyze_code(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
241 """Analyze Unity code."""
242 server = UnityLLMBridgeServer()
243 server.set_unity_context(context)
244 await server.initialize()
245
246 try:
247 result = await server.call_tool('analyze_unity_code', {
248 'code': input_data.get('codeToAnalyze', ''),
249 'analysis_type': 'general'
250 })
251 return result.get('result', result)
252 finally:
253 await server.shutdown()
254
255
256async def text_to_speech(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
257 """Convert text to speech."""
258 server = EdenAIUnityServer()
259 server.set_unity_context(context)
260 await server.initialize()
261
262 try:
263 result = await server.call_tool('text_to_speech_unity', {
264 'text': input_data.get('textToSpeak', ''),
265 'voice': 'default',
266 'language': 'en-US',
267 'output_format': 'wav'
268 })
269 return result.get('result', result)
270 finally:
271 await server.shutdown()
272
273
274async def npc_dialogue(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
275 """Generate NPC dialogue."""
276 server = EdenAIUnityServer()
277 server.set_unity_context(context)
278 await server.initialize()
279
280 try:
281 result = await server.call_tool('chatbot_npc_dialogue', {
282 'npc_role': input_data.get('scriptDescription', 'Merchant'),
283 'context': '',
284 'player_input': input_data.get('llmPrompt', 'Hello'),
285 'dialogue_options': 3,
286 'tone': 'neutral'
287 })
288 return result.get('result', result)
289 finally:
290 await server.shutdown()
291
292
293async def translate_ui(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
294 """Translate UI elements."""
295 server = EdenAIUnityServer()
296 server.set_unity_context(context)
297 await server.initialize()
298
299 try:
300 result = await server.call_tool('translation_localization', {
301 'texts': input_data.get('textsToTranslate', []),
302 'source_language': 'en',
303 'target_languages': input_data.get('targetLanguages', ['es']),
304 'preserve_formatting': True
305 })
306 return result.get('result', result)
307 finally:
308 await server.shutdown()
309
310
311async def vision_analysis(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
312 """Analyze texture/image."""
313 server = EdenAIUnityServer()
314 server.set_unity_context(context)
315 await server.initialize()
316
317 try:
318 result = await server.call_tool('vision_analysis_texture2d', {
319 'texture_data': input_data.get('codeToAnalyze', ''),
320 'analysis_type': 'object_detection'
321 })
322 return result.get('result', result)
323 finally:
324 await server.shutdown()
325
326
327async def deploy_cloud_code(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
328 """Deploy cloud code."""
329 server = UnityCloudServicesServer()
330 server.set_unity_context(context)
331 await server.initialize()
332
333 try:
334 result = await server.call_tool('deploy_cloud_code', {
335 'script_name': input_data.get('scriptName', 'CloudScript'),
336 'script_content': input_data.get('codeToAnalyze', ''),
337 'environment': 'production',
338 'parameters': {}
339 })
340 return result.get('result', result)
341 finally:
342 await server.shutdown()
343
344
345async def manage_remote_config(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
346 """Manage remote config."""
347 server = UnityCloudServicesServer()
348 server.set_unity_context(context)
349 await server.initialize()
350
351 try:
352 result = await server.call_tool('manage_remote_config', {
353 'config_key': input_data.get('scriptName', 'config_key'),
354 'config_value': input_data.get('scriptDescription', ''),
355 'environment': 'production'
356 })
357 return result.get('result', result)
358 finally:
359 await server.shutdown()
360
361
362async def query_analytics(input_data: Dict[str, Any], context: UnityContext) -> Dict[str, Any]:
363 """Query analytics."""
364 server = UnityCloudServicesServer()
365 server.set_unity_context(context)
366 await server.initialize()
367
368 try:
369 result = await server.call_tool('query_analytics', {
370 'metric': 'daily_active_users',
371 'start_date': '2025-01-01',
372 'end_date': '2025-01-13',
373 'filters': {},
374 'aggregation': 'daily'
375 })
376 return result.get('result', result)
377 finally:
378 await server.shutdown()
379
380
381if __name__ == '__main__':
382 asyncio.run(main())