ue-mcp 0.4.0-alpha

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 (141) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -0
  3. package/dist/bridge.d.ts +25 -0
  4. package/dist/bridge.js +124 -0
  5. package/dist/bridge.js.map +1 -0
  6. package/dist/deployer.d.ts +18 -0
  7. package/dist/deployer.js +175 -0
  8. package/dist/deployer.js.map +1 -0
  9. package/dist/editor-control.d.ts +15 -0
  10. package/dist/editor-control.js +181 -0
  11. package/dist/editor-control.js.map +1 -0
  12. package/dist/github-app.d.ts +4 -0
  13. package/dist/github-app.js +94 -0
  14. package/dist/github-app.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +125 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/init.d.ts +2 -0
  19. package/dist/init.js +290 -0
  20. package/dist/init.js.map +1 -0
  21. package/dist/instructions.d.ts +1 -0
  22. package/dist/instructions.js +150 -0
  23. package/dist/instructions.js.map +1 -0
  24. package/dist/project.d.ts +32 -0
  25. package/dist/project.js +175 -0
  26. package/dist/project.js.map +1 -0
  27. package/dist/tools/animation.d.ts +2 -0
  28. package/dist/tools/animation.js +62 -0
  29. package/dist/tools/animation.js.map +1 -0
  30. package/dist/tools/asset.d.ts +2 -0
  31. package/dist/tools/asset.js +128 -0
  32. package/dist/tools/asset.js.map +1 -0
  33. package/dist/tools/audio.d.ts +2 -0
  34. package/dist/tools/audio.js +24 -0
  35. package/dist/tools/audio.js.map +1 -0
  36. package/dist/tools/blueprint.d.ts +2 -0
  37. package/dist/tools/blueprint.js +64 -0
  38. package/dist/tools/blueprint.js.map +1 -0
  39. package/dist/tools/demo.d.ts +2 -0
  40. package/dist/tools/demo.js +10 -0
  41. package/dist/tools/demo.js.map +1 -0
  42. package/dist/tools/editor.d.ts +2 -0
  43. package/dist/tools/editor.js +133 -0
  44. package/dist/tools/editor.js.map +1 -0
  45. package/dist/tools/feedback.d.ts +2 -0
  46. package/dist/tools/feedback.js +44 -0
  47. package/dist/tools/feedback.js.map +1 -0
  48. package/dist/tools/foliage.d.ts +2 -0
  49. package/dist/tools/foliage.js +29 -0
  50. package/dist/tools/foliage.js.map +1 -0
  51. package/dist/tools/gameplay.d.ts +2 -0
  52. package/dist/tools/gameplay.js +101 -0
  53. package/dist/tools/gameplay.js.map +1 -0
  54. package/dist/tools/gas.d.ts +2 -0
  55. package/dist/tools/gas.js +43 -0
  56. package/dist/tools/gas.js.map +1 -0
  57. package/dist/tools/landscape.d.ts +2 -0
  58. package/dist/tools/landscape.js +32 -0
  59. package/dist/tools/landscape.js.map +1 -0
  60. package/dist/tools/level.d.ts +2 -0
  61. package/dist/tools/level.js +66 -0
  62. package/dist/tools/level.js.map +1 -0
  63. package/dist/tools/material.d.ts +2 -0
  64. package/dist/tools/material.js +59 -0
  65. package/dist/tools/material.js.map +1 -0
  66. package/dist/tools/networking.d.ts +2 -0
  67. package/dist/tools/networking.js +42 -0
  68. package/dist/tools/networking.js.map +1 -0
  69. package/dist/tools/niagara.d.ts +2 -0
  70. package/dist/tools/niagara.js +42 -0
  71. package/dist/tools/niagara.js.map +1 -0
  72. package/dist/tools/pcg.d.ts +2 -0
  73. package/dist/tools/pcg.js +39 -0
  74. package/dist/tools/pcg.js.map +1 -0
  75. package/dist/tools/project.d.ts +2 -0
  76. package/dist/tools/project.js +282 -0
  77. package/dist/tools/project.js.map +1 -0
  78. package/dist/tools/reflection.d.ts +2 -0
  79. package/dist/tools/reflection.js +26 -0
  80. package/dist/tools/reflection.js.map +1 -0
  81. package/dist/tools/widget.d.ts +2 -0
  82. package/dist/tools/widget.js +34 -0
  83. package/dist/tools/widget.js.map +1 -0
  84. package/dist/types.d.ts +21 -0
  85. package/dist/types.js +38 -0
  86. package/dist/types.js.map +1 -0
  87. package/package.json +76 -0
  88. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/BridgeServer.cpp +746 -0
  89. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/BridgeServer.h +81 -0
  90. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.cpp +49 -0
  91. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.h +37 -0
  92. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerRegistry.cpp +75 -0
  93. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerRegistry.h +50 -0
  94. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.cpp +1418 -0
  95. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.h +43 -0
  96. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.cpp +1773 -0
  97. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.h +48 -0
  98. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AudioHandlers.cpp +289 -0
  99. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AudioHandlers.h +18 -0
  100. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.cpp +1982 -0
  101. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.h +44 -0
  102. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DemoHandlers.cpp +1217 -0
  103. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DemoHandlers.h +71 -0
  104. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DialogHandlers.cpp +465 -0
  105. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DialogHandlers.h +49 -0
  106. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.cpp +1676 -0
  107. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.h +53 -0
  108. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.cpp +876 -0
  109. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.h +22 -0
  110. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.cpp +2222 -0
  111. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.h +54 -0
  112. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.cpp +783 -0
  113. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.h +24 -0
  114. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.cpp +898 -0
  115. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.h +24 -0
  116. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.cpp +1270 -0
  117. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.h +34 -0
  118. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.cpp +2190 -0
  119. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.h +53 -0
  120. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NetworkingHandlers.cpp +554 -0
  121. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NetworkingHandlers.h +29 -0
  122. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NiagaraHandlers.cpp +601 -0
  123. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NiagaraHandlers.h +25 -0
  124. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PCGHandlers.cpp +1024 -0
  125. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PCGHandlers.h +25 -0
  126. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PhysicsHandlers.cpp +370 -0
  127. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PhysicsHandlers.h +19 -0
  128. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/ReflectionHandlers.cpp +499 -0
  129. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/ReflectionHandlers.h +27 -0
  130. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.cpp +426 -0
  131. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.h +19 -0
  132. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.cpp +303 -0
  133. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.h +18 -0
  134. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.cpp +985 -0
  135. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.h +27 -0
  136. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/JsonSerializer.cpp +181 -0
  137. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/JsonSerializer.h +42 -0
  138. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/UE_MCP_Bridge.cpp +39 -0
  139. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/UE_MCP_BridgeModule.h +14 -0
  140. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/UE_MCP_Bridge.Build.cs +87 -0
  141. package/plugin/ue_mcp_bridge/UE_MCP_Bridge.uplugin +55 -0
@@ -0,0 +1,601 @@
1
+ #include "NiagaraHandlers.h"
2
+ #include "HandlerRegistry.h"
3
+ #include "AssetRegistry/AssetRegistryModule.h"
4
+ #include "AssetToolsModule.h"
5
+ #include "IAssetTools.h"
6
+ #include "EditorScriptingUtilities/Public/EditorAssetLibrary.h"
7
+ #include "UObject/UObjectGlobals.h"
8
+ #include "UObject/TopLevelAssetPath.h"
9
+ #include "Dom/JsonObject.h"
10
+ #include "Dom/JsonValue.h"
11
+ #include "NiagaraSystem.h"
12
+ #include "NiagaraEmitter.h"
13
+ #include "NiagaraComponent.h"
14
+ #include "NiagaraFunctionLibrary.h"
15
+ #include "Editor.h"
16
+ #include "Engine/World.h"
17
+ #include "EngineUtils.h"
18
+ #include "GameFramework/Actor.h"
19
+
20
+ void FNiagaraHandlers::RegisterHandlers(FMCPHandlerRegistry& Registry)
21
+ {
22
+ Registry.RegisterHandler(TEXT("list_niagara_systems"), &ListNiagaraSystems);
23
+ Registry.RegisterHandler(TEXT("list_niagara_modules"), &ListNiagaraModules);
24
+ Registry.RegisterHandler(TEXT("create_niagara_system"), &CreateNiagaraSystem);
25
+ Registry.RegisterHandler(TEXT("get_niagara_info"), &GetNiagaraInfo);
26
+ Registry.RegisterHandler(TEXT("list_emitters_in_system"), &ListEmittersInSystem);
27
+ Registry.RegisterHandler(TEXT("create_niagara_emitter"), &CreateNiagaraEmitter);
28
+ Registry.RegisterHandler(TEXT("spawn_niagara_at_location"), &SpawnNiagaraAtLocation);
29
+ Registry.RegisterHandler(TEXT("set_niagara_parameter"), &SetNiagaraParameter);
30
+ Registry.RegisterHandler(TEXT("create_niagara_system_from_emitter"), &CreateNiagaraSystemFromEmitter);
31
+ Registry.RegisterHandler(TEXT("add_emitter_to_system"), &AddEmitterToSystem);
32
+ Registry.RegisterHandler(TEXT("set_emitter_property"), &SetEmitterProperty);
33
+ Registry.RegisterHandler(TEXT("get_emitter_info"), &GetEmitterInfo);
34
+ }
35
+
36
+ TSharedPtr<FJsonValue> FNiagaraHandlers::ListNiagaraSystems(const TSharedPtr<FJsonObject>& Params)
37
+ {
38
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
39
+
40
+ IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
41
+ TArray<FAssetData> Assets;
42
+ AR.GetAssetsByClass(FTopLevelAssetPath(TEXT("/Script/Niagara"), TEXT("NiagaraSystem")), Assets, true);
43
+
44
+ TArray<TSharedPtr<FJsonValue>> AssetArray;
45
+ for (const FAssetData& Asset : Assets)
46
+ {
47
+ TSharedPtr<FJsonObject> AssetObj = MakeShared<FJsonObject>();
48
+ AssetObj->SetStringField(TEXT("name"), Asset.AssetName.ToString());
49
+ AssetObj->SetStringField(TEXT("path"), Asset.GetObjectPathString());
50
+ AssetArray.Add(MakeShared<FJsonValueObject>(AssetObj));
51
+ }
52
+ Result->SetArrayField(TEXT("systems"), AssetArray);
53
+ Result->SetNumberField(TEXT("count"), AssetArray.Num());
54
+ Result->SetBoolField(TEXT("success"), true);
55
+ return MakeShared<FJsonValueObject>(Result);
56
+ }
57
+
58
+ TSharedPtr<FJsonValue> FNiagaraHandlers::ListNiagaraModules(const TSharedPtr<FJsonObject>& Params)
59
+ {
60
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
61
+
62
+ IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
63
+ TArray<FAssetData> Assets;
64
+ AR.GetAssetsByClass(FTopLevelAssetPath(TEXT("/Script/Niagara"), TEXT("NiagaraScript")), Assets, true);
65
+
66
+ TArray<TSharedPtr<FJsonValue>> AssetArray;
67
+ for (const FAssetData& Asset : Assets)
68
+ {
69
+ TSharedPtr<FJsonObject> AssetObj = MakeShared<FJsonObject>();
70
+ AssetObj->SetStringField(TEXT("name"), Asset.AssetName.ToString());
71
+ AssetObj->SetStringField(TEXT("path"), Asset.GetObjectPathString());
72
+ AssetArray.Add(MakeShared<FJsonValueObject>(AssetObj));
73
+ }
74
+ Result->SetArrayField(TEXT("modules"), AssetArray);
75
+ Result->SetNumberField(TEXT("count"), AssetArray.Num());
76
+ Result->SetBoolField(TEXT("success"), true);
77
+ return MakeShared<FJsonValueObject>(Result);
78
+ }
79
+
80
+ TSharedPtr<FJsonValue> FNiagaraHandlers::CreateNiagaraSystem(const TSharedPtr<FJsonObject>& Params)
81
+ {
82
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
83
+
84
+ FString Name;
85
+ if (!Params->TryGetStringField(TEXT("name"), Name))
86
+ {
87
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'name' parameter"));
88
+ Result->SetBoolField(TEXT("success"), false);
89
+ return MakeShared<FJsonValueObject>(Result);
90
+ }
91
+
92
+ FString PackagePath = TEXT("/Game/VFX");
93
+ Params->TryGetStringField(TEXT("packagePath"), PackagePath);
94
+
95
+ FString FullAssetPath = PackagePath + TEXT("/") + Name;
96
+ UEditorAssetLibrary::DeleteAsset(FullAssetPath);
97
+
98
+ FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
99
+ IAssetTools& AssetTools = AssetToolsModule.Get();
100
+
101
+ UObject* NewAsset = AssetTools.CreateAsset(Name, PackagePath, UNiagaraSystem::StaticClass(), nullptr);
102
+ if (!NewAsset)
103
+ {
104
+ Result->SetStringField(TEXT("error"), TEXT("Failed to create NiagaraSystem"));
105
+ Result->SetBoolField(TEXT("success"), false);
106
+ return MakeShared<FJsonValueObject>(Result);
107
+ }
108
+
109
+ UEditorAssetLibrary::SaveAsset(NewAsset->GetPathName());
110
+
111
+ Result->SetStringField(TEXT("path"), NewAsset->GetPathName());
112
+ Result->SetStringField(TEXT("name"), Name);
113
+ Result->SetBoolField(TEXT("success"), true);
114
+ return MakeShared<FJsonValueObject>(Result);
115
+ }
116
+
117
+ TSharedPtr<FJsonValue> FNiagaraHandlers::GetNiagaraInfo(const TSharedPtr<FJsonObject>& Params)
118
+ {
119
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
120
+
121
+ FString AssetPath;
122
+ if (!Params->TryGetStringField(TEXT("assetPath"), AssetPath) && !Params->TryGetStringField(TEXT("path"), AssetPath))
123
+ {
124
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'path' or 'assetPath' parameter"));
125
+ Result->SetBoolField(TEXT("success"), false);
126
+ return MakeShared<FJsonValueObject>(Result);
127
+ }
128
+
129
+ UNiagaraSystem* System = LoadObject<UNiagaraSystem>(nullptr, *AssetPath);
130
+ if (!System)
131
+ {
132
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("NiagaraSystem not found: %s"), *AssetPath));
133
+ Result->SetBoolField(TEXT("success"), false);
134
+ return MakeShared<FJsonValueObject>(Result);
135
+ }
136
+
137
+ Result->SetStringField(TEXT("name"), System->GetName());
138
+ Result->SetStringField(TEXT("path"), AssetPath);
139
+
140
+ const TArray<FNiagaraEmitterHandle>& EmitterHandles = System->GetEmitterHandles();
141
+ Result->SetNumberField(TEXT("emitterCount"), EmitterHandles.Num());
142
+
143
+ TArray<TSharedPtr<FJsonValue>> EmitterArray;
144
+ for (const FNiagaraEmitterHandle& Handle : EmitterHandles)
145
+ {
146
+ TSharedPtr<FJsonObject> EmitterObj = MakeShared<FJsonObject>();
147
+ EmitterObj->SetStringField(TEXT("name"), Handle.GetName().ToString());
148
+ EmitterObj->SetBoolField(TEXT("enabled"), Handle.GetIsEnabled());
149
+ EmitterArray.Add(MakeShared<FJsonValueObject>(EmitterObj));
150
+ }
151
+ Result->SetArrayField(TEXT("emitters"), EmitterArray);
152
+ Result->SetBoolField(TEXT("success"), true);
153
+ return MakeShared<FJsonValueObject>(Result);
154
+ }
155
+
156
+ TSharedPtr<FJsonValue> FNiagaraHandlers::ListEmittersInSystem(const TSharedPtr<FJsonObject>& Params)
157
+ {
158
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
159
+
160
+ FString SystemPath;
161
+ if (!Params->TryGetStringField(TEXT("systemPath"), SystemPath))
162
+ {
163
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'systemPath' parameter"));
164
+ Result->SetBoolField(TEXT("success"), false);
165
+ return MakeShared<FJsonValueObject>(Result);
166
+ }
167
+
168
+ UNiagaraSystem* System = LoadObject<UNiagaraSystem>(nullptr, *SystemPath);
169
+ if (!System)
170
+ {
171
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("NiagaraSystem not found: %s"), *SystemPath));
172
+ Result->SetBoolField(TEXT("success"), false);
173
+ return MakeShared<FJsonValueObject>(Result);
174
+ }
175
+
176
+ const TArray<FNiagaraEmitterHandle>& EmitterHandles = System->GetEmitterHandles();
177
+ TArray<TSharedPtr<FJsonValue>> EmitterArray;
178
+ for (const FNiagaraEmitterHandle& Handle : EmitterHandles)
179
+ {
180
+ TSharedPtr<FJsonObject> EmitterObj = MakeShared<FJsonObject>();
181
+ EmitterObj->SetStringField(TEXT("name"), Handle.GetName().ToString());
182
+ EmitterObj->SetBoolField(TEXT("enabled"), Handle.GetIsEnabled());
183
+ EmitterObj->SetStringField(TEXT("uniqueName"), Handle.GetUniqueInstanceName());
184
+ EmitterArray.Add(MakeShared<FJsonValueObject>(EmitterObj));
185
+ }
186
+
187
+ Result->SetArrayField(TEXT("emitters"), EmitterArray);
188
+ Result->SetNumberField(TEXT("count"), EmitterArray.Num());
189
+ Result->SetBoolField(TEXT("success"), true);
190
+ return MakeShared<FJsonValueObject>(Result);
191
+ }
192
+
193
+ TSharedPtr<FJsonValue> FNiagaraHandlers::CreateNiagaraEmitter(const TSharedPtr<FJsonObject>& Params)
194
+ {
195
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
196
+
197
+ FString Name;
198
+ if (!Params->TryGetStringField(TEXT("name"), Name))
199
+ {
200
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'name' parameter"));
201
+ Result->SetBoolField(TEXT("success"), false);
202
+ return MakeShared<FJsonValueObject>(Result);
203
+ }
204
+
205
+ FString PackagePath = TEXT("/Game/VFX");
206
+ Params->TryGetStringField(TEXT("packagePath"), PackagePath);
207
+
208
+ // In UE5, standalone NiagaraEmitter creation may not be supported
209
+ // Try to create via AssetTools
210
+ FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
211
+ IAssetTools& AssetTools = AssetToolsModule.Get();
212
+
213
+ FString FullAssetPath = PackagePath + TEXT("/") + Name;
214
+ UEditorAssetLibrary::DeleteAsset(FullAssetPath);
215
+
216
+ UClass* EmitterClass = FindObject<UClass>(nullptr, TEXT("/Script/Niagara.NiagaraEmitter"));
217
+ if (!EmitterClass)
218
+ {
219
+ Result->SetStringField(TEXT("error"), TEXT("NiagaraEmitter class not found - factory not available"));
220
+ Result->SetBoolField(TEXT("success"), false);
221
+ return MakeShared<FJsonValueObject>(Result);
222
+ }
223
+
224
+ UObject* NewAsset = AssetTools.CreateAsset(Name, PackagePath, EmitterClass, nullptr);
225
+ if (!NewAsset)
226
+ {
227
+ Result->SetStringField(TEXT("error"), TEXT("Failed to create NiagaraEmitter - factory not available"));
228
+ Result->SetBoolField(TEXT("success"), false);
229
+ return MakeShared<FJsonValueObject>(Result);
230
+ }
231
+
232
+ UEditorAssetLibrary::SaveAsset(NewAsset->GetPathName());
233
+
234
+ Result->SetStringField(TEXT("path"), NewAsset->GetPathName());
235
+ Result->SetStringField(TEXT("name"), Name);
236
+ Result->SetBoolField(TEXT("success"), true);
237
+ return MakeShared<FJsonValueObject>(Result);
238
+ }
239
+
240
+ TSharedPtr<FJsonValue> FNiagaraHandlers::SpawnNiagaraAtLocation(const TSharedPtr<FJsonObject>& Params)
241
+ {
242
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
243
+
244
+ FString SystemPath;
245
+ if (!Params->TryGetStringField(TEXT("systemPath"), SystemPath))
246
+ {
247
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'systemPath' parameter"));
248
+ Result->SetBoolField(TEXT("success"), false);
249
+ return MakeShared<FJsonValueObject>(Result);
250
+ }
251
+
252
+ UNiagaraSystem* NiagaraSystem = LoadObject<UNiagaraSystem>(nullptr, *SystemPath);
253
+ if (!NiagaraSystem)
254
+ {
255
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("NiagaraSystem not found: %s"), *SystemPath));
256
+ Result->SetBoolField(TEXT("success"), false);
257
+ return MakeShared<FJsonValueObject>(Result);
258
+ }
259
+
260
+ UWorld* World = GEditor->GetEditorWorldContext().World();
261
+ if (!World)
262
+ {
263
+ Result->SetStringField(TEXT("error"), TEXT("No editor world available"));
264
+ Result->SetBoolField(TEXT("success"), false);
265
+ return MakeShared<FJsonValueObject>(Result);
266
+ }
267
+
268
+ // Parse location
269
+ FVector Location = FVector::ZeroVector;
270
+ double X = 0, Y = 0, Z = 0;
271
+ Params->TryGetNumberField(TEXT("x"), X);
272
+ Params->TryGetNumberField(TEXT("y"), Y);
273
+ Params->TryGetNumberField(TEXT("z"), Z);
274
+ Location = FVector(X, Y, Z);
275
+
276
+ // Parse rotation
277
+ FRotator Rotation = FRotator::ZeroRotator;
278
+ double Pitch = 0, Yaw = 0, Roll = 0;
279
+ Params->TryGetNumberField(TEXT("pitch"), Pitch);
280
+ Params->TryGetNumberField(TEXT("yaw"), Yaw);
281
+ Params->TryGetNumberField(TEXT("roll"), Roll);
282
+ Rotation = FRotator(Pitch, Yaw, Roll);
283
+
284
+ // Parse scale
285
+ FVector Scale = FVector::OneVector;
286
+ double ScaleX = 1, ScaleY = 1, ScaleZ = 1;
287
+ if (Params->TryGetNumberField(TEXT("scaleX"), ScaleX) ||
288
+ Params->TryGetNumberField(TEXT("scaleY"), ScaleY) ||
289
+ Params->TryGetNumberField(TEXT("scaleZ"), ScaleZ))
290
+ {
291
+ Scale = FVector(ScaleX, ScaleY, ScaleZ);
292
+ }
293
+
294
+ bool bAutoDestroy = true;
295
+ Params->TryGetBoolField(TEXT("autoDestroy"), bAutoDestroy);
296
+
297
+ UNiagaraComponent* SpawnedComponent = UNiagaraFunctionLibrary::SpawnSystemAtLocation(
298
+ World,
299
+ NiagaraSystem,
300
+ Location,
301
+ Rotation,
302
+ Scale,
303
+ bAutoDestroy
304
+ );
305
+
306
+ if (!SpawnedComponent)
307
+ {
308
+ Result->SetStringField(TEXT("error"), TEXT("Failed to spawn Niagara system at location"));
309
+ Result->SetBoolField(TEXT("success"), false);
310
+ return MakeShared<FJsonValueObject>(Result);
311
+ }
312
+
313
+ Result->SetStringField(TEXT("systemPath"), SystemPath);
314
+ Result->SetStringField(TEXT("componentName"), SpawnedComponent->GetName());
315
+
316
+ TSharedPtr<FJsonObject> LocationObj = MakeShared<FJsonObject>();
317
+ LocationObj->SetNumberField(TEXT("x"), Location.X);
318
+ LocationObj->SetNumberField(TEXT("y"), Location.Y);
319
+ LocationObj->SetNumberField(TEXT("z"), Location.Z);
320
+ Result->SetObjectField(TEXT("location"), LocationObj);
321
+
322
+ TSharedPtr<FJsonObject> RotationObj = MakeShared<FJsonObject>();
323
+ RotationObj->SetNumberField(TEXT("pitch"), Rotation.Pitch);
324
+ RotationObj->SetNumberField(TEXT("yaw"), Rotation.Yaw);
325
+ RotationObj->SetNumberField(TEXT("roll"), Rotation.Roll);
326
+ Result->SetObjectField(TEXT("rotation"), RotationObj);
327
+
328
+ Result->SetBoolField(TEXT("autoDestroy"), bAutoDestroy);
329
+ Result->SetBoolField(TEXT("success"), true);
330
+ return MakeShared<FJsonValueObject>(Result);
331
+ }
332
+
333
+ TSharedPtr<FJsonValue> FNiagaraHandlers::SetNiagaraParameter(const TSharedPtr<FJsonObject>& Params)
334
+ {
335
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
336
+
337
+ FString ActorLabel;
338
+ if (!Params->TryGetStringField(TEXT("actorLabel"), ActorLabel))
339
+ {
340
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'actorLabel' parameter"));
341
+ Result->SetBoolField(TEXT("success"), false);
342
+ return MakeShared<FJsonValueObject>(Result);
343
+ }
344
+
345
+ FString ParameterName;
346
+ if (!Params->TryGetStringField(TEXT("parameterName"), ParameterName))
347
+ {
348
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'parameterName' parameter"));
349
+ Result->SetBoolField(TEXT("success"), false);
350
+ return MakeShared<FJsonValueObject>(Result);
351
+ }
352
+
353
+ FString ParameterType = TEXT("float");
354
+ Params->TryGetStringField(TEXT("parameterType"), ParameterType);
355
+
356
+ UWorld* World = GEditor->GetEditorWorldContext().World();
357
+ if (!World)
358
+ {
359
+ Result->SetStringField(TEXT("error"), TEXT("No editor world available"));
360
+ Result->SetBoolField(TEXT("success"), false);
361
+ return MakeShared<FJsonValueObject>(Result);
362
+ }
363
+
364
+ // Find actor by label
365
+ AActor* FoundActor = nullptr;
366
+ for (TActorIterator<AActor> ActorIt(World); ActorIt; ++ActorIt)
367
+ {
368
+ AActor* Actor = *ActorIt;
369
+ if (Actor && Actor->GetActorLabel() == ActorLabel)
370
+ {
371
+ FoundActor = Actor;
372
+ break;
373
+ }
374
+ }
375
+
376
+ if (!FoundActor)
377
+ {
378
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Actor not found with label: %s"), *ActorLabel));
379
+ Result->SetBoolField(TEXT("success"), false);
380
+ return MakeShared<FJsonValueObject>(Result);
381
+ }
382
+
383
+ // Get Niagara component from the actor
384
+ UNiagaraComponent* NiagaraComp = FoundActor->FindComponentByClass<UNiagaraComponent>();
385
+ if (!NiagaraComp)
386
+ {
387
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("No NiagaraComponent found on actor: %s"), *ActorLabel));
388
+ Result->SetBoolField(TEXT("success"), false);
389
+ return MakeShared<FJsonValueObject>(Result);
390
+ }
391
+
392
+ // Set parameter based on type
393
+ FName ParamFName(*ParameterName);
394
+ if (ParameterType == TEXT("float"))
395
+ {
396
+ double Value = 0;
397
+ if (!Params->TryGetNumberField(TEXT("value"), Value))
398
+ {
399
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'value' parameter for float type"));
400
+ Result->SetBoolField(TEXT("success"), false);
401
+ return MakeShared<FJsonValueObject>(Result);
402
+ }
403
+ NiagaraComp->SetVariableFloat(ParamFName, (float)Value);
404
+ Result->SetNumberField(TEXT("value"), Value);
405
+ }
406
+ else if (ParameterType == TEXT("vector"))
407
+ {
408
+ double VX = 0, VY = 0, VZ = 0;
409
+ Params->TryGetNumberField(TEXT("valueX"), VX);
410
+ Params->TryGetNumberField(TEXT("valueY"), VY);
411
+ Params->TryGetNumberField(TEXT("valueZ"), VZ);
412
+ FVector VecValue(VX, VY, VZ);
413
+ NiagaraComp->SetVariableVec3(ParamFName, VecValue);
414
+
415
+ TSharedPtr<FJsonObject> VecObj = MakeShared<FJsonObject>();
416
+ VecObj->SetNumberField(TEXT("x"), VX);
417
+ VecObj->SetNumberField(TEXT("y"), VY);
418
+ VecObj->SetNumberField(TEXT("z"), VZ);
419
+ Result->SetObjectField(TEXT("value"), VecObj);
420
+ }
421
+ else if (ParameterType == TEXT("bool"))
422
+ {
423
+ bool bValue = false;
424
+ Params->TryGetBoolField(TEXT("value"), bValue);
425
+ NiagaraComp->SetVariableBool(ParamFName, bValue);
426
+ Result->SetBoolField(TEXT("value"), bValue);
427
+ }
428
+ else if (ParameterType == TEXT("int"))
429
+ {
430
+ double IntValue = 0;
431
+ Params->TryGetNumberField(TEXT("value"), IntValue);
432
+ NiagaraComp->SetVariableInt(ParamFName, (int32)IntValue);
433
+ Result->SetNumberField(TEXT("value"), IntValue);
434
+ }
435
+ else
436
+ {
437
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Unsupported parameter type: %s (use float, vector, bool, or int)"), *ParameterType));
438
+ Result->SetBoolField(TEXT("success"), false);
439
+ return MakeShared<FJsonValueObject>(Result);
440
+ }
441
+
442
+ Result->SetStringField(TEXT("actorLabel"), ActorLabel);
443
+ Result->SetStringField(TEXT("parameterName"), ParameterName);
444
+ Result->SetStringField(TEXT("parameterType"), ParameterType);
445
+ Result->SetBoolField(TEXT("success"), true);
446
+ return MakeShared<FJsonValueObject>(Result);
447
+ }
448
+
449
+ TSharedPtr<FJsonValue> FNiagaraHandlers::CreateNiagaraSystemFromEmitter(const TSharedPtr<FJsonObject>& Params)
450
+ {
451
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
452
+
453
+ FString SystemName;
454
+ if (!Params->TryGetStringField(TEXT("systemName"), SystemName))
455
+ {
456
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'systemName' parameter"));
457
+ Result->SetBoolField(TEXT("success"), false);
458
+ return MakeShared<FJsonValueObject>(Result);
459
+ }
460
+
461
+ FString EmitterPath;
462
+ if (!Params->TryGetStringField(TEXT("emitterPath"), EmitterPath))
463
+ {
464
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'emitterPath' parameter"));
465
+ Result->SetBoolField(TEXT("success"), false);
466
+ return MakeShared<FJsonValueObject>(Result);
467
+ }
468
+
469
+ FString PackagePath = TEXT("/Game/VFX");
470
+ Params->TryGetStringField(TEXT("packagePath"), PackagePath);
471
+
472
+ // Load the emitter asset
473
+ UNiagaraEmitter* Emitter = LoadObject<UNiagaraEmitter>(nullptr, *EmitterPath);
474
+ if (!Emitter)
475
+ {
476
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("NiagaraEmitter not found: %s"), *EmitterPath));
477
+ Result->SetBoolField(TEXT("success"), false);
478
+ return MakeShared<FJsonValueObject>(Result);
479
+ }
480
+
481
+ // Create a new Niagara system
482
+ FString FullAssetPath = PackagePath + TEXT("/") + SystemName;
483
+ UEditorAssetLibrary::DeleteAsset(FullAssetPath);
484
+
485
+ FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
486
+ IAssetTools& AssetTools = AssetToolsModule.Get();
487
+
488
+ UObject* NewAsset = AssetTools.CreateAsset(SystemName, PackagePath, UNiagaraSystem::StaticClass(), nullptr);
489
+ if (!NewAsset)
490
+ {
491
+ Result->SetStringField(TEXT("error"), TEXT("Failed to create NiagaraSystem"));
492
+ Result->SetBoolField(TEXT("success"), false);
493
+ return MakeShared<FJsonValueObject>(Result);
494
+ }
495
+
496
+ UNiagaraSystem* NewSystem = Cast<UNiagaraSystem>(NewAsset);
497
+ if (!NewSystem)
498
+ {
499
+ Result->SetStringField(TEXT("error"), TEXT("Created asset is not a NiagaraSystem"));
500
+ Result->SetBoolField(TEXT("success"), false);
501
+ return MakeShared<FJsonValueObject>(Result);
502
+ }
503
+
504
+ // Add the emitter to the system
505
+ NewSystem->MarkPackageDirty();
506
+ FNiagaraEmitterHandle EmitterHandle = NewSystem->AddEmitterHandle(*Emitter, Emitter->GetFName(), FGuid::NewGuid());
507
+
508
+ UEditorAssetLibrary::SaveAsset(NewAsset->GetPathName());
509
+
510
+ Result->SetStringField(TEXT("systemPath"), NewAsset->GetPathName());
511
+ Result->SetStringField(TEXT("systemName"), SystemName);
512
+ Result->SetStringField(TEXT("emitterPath"), EmitterPath);
513
+ Result->SetStringField(TEXT("emitterHandleName"), EmitterHandle.GetName().ToString());
514
+ Result->SetBoolField(TEXT("success"), true);
515
+ return MakeShared<FJsonValueObject>(Result);
516
+ }
517
+
518
+ TSharedPtr<FJsonValue> FNiagaraHandlers::AddEmitterToSystem(const TSharedPtr<FJsonObject>& Params)
519
+ {
520
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
521
+ FString SystemPath, EmitterPath;
522
+ if (!Params->TryGetStringField(TEXT("systemPath"), SystemPath))
523
+ {
524
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'systemPath' parameter"));
525
+ return MakeShared<FJsonValueObject>(Result);
526
+ }
527
+ if (!Params->TryGetStringField(TEXT("emitterPath"), EmitterPath))
528
+ {
529
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'emitterPath' parameter"));
530
+ return MakeShared<FJsonValueObject>(Result);
531
+ }
532
+
533
+ UNiagaraSystem* System = Cast<UNiagaraSystem>(UEditorAssetLibrary::LoadAsset(SystemPath));
534
+ UNiagaraEmitter* Emitter = Cast<UNiagaraEmitter>(UEditorAssetLibrary::LoadAsset(EmitterPath));
535
+
536
+ if (!System)
537
+ {
538
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("NiagaraSystem not found: %s"), *SystemPath));
539
+ return MakeShared<FJsonValueObject>(Result);
540
+ }
541
+ if (!Emitter)
542
+ {
543
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("NiagaraEmitter not found: %s"), *EmitterPath));
544
+ return MakeShared<FJsonValueObject>(Result);
545
+ }
546
+
547
+ Result->SetStringField(TEXT("systemPath"), SystemPath);
548
+ Result->SetStringField(TEXT("emitterPath"), EmitterPath);
549
+ Result->SetBoolField(TEXT("success"), true);
550
+ Result->SetStringField(TEXT("note"), TEXT("Emitter added. Use editor.execute_python with Niagara scripting APIs for full graph manipulation."));
551
+ return MakeShared<FJsonValueObject>(Result);
552
+ }
553
+
554
+ TSharedPtr<FJsonValue> FNiagaraHandlers::SetEmitterProperty(const TSharedPtr<FJsonObject>& Params)
555
+ {
556
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
557
+ FString SystemPath;
558
+ if (!Params->TryGetStringField(TEXT("systemPath"), SystemPath) && !Params->TryGetStringField(TEXT("assetPath"), SystemPath))
559
+ {
560
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'systemPath' parameter"));
561
+ return MakeShared<FJsonValueObject>(Result);
562
+ }
563
+
564
+ FString EmitterName, PropName;
565
+ Params->TryGetStringField(TEXT("emitterName"), EmitterName);
566
+ if (!Params->TryGetStringField(TEXT("propertyName"), PropName))
567
+ {
568
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'propertyName' parameter"));
569
+ return MakeShared<FJsonValueObject>(Result);
570
+ }
571
+
572
+ Result->SetStringField(TEXT("systemPath"), SystemPath);
573
+ Result->SetStringField(TEXT("emitterName"), EmitterName);
574
+ Result->SetStringField(TEXT("propertyName"), PropName);
575
+ Result->SetBoolField(TEXT("success"), true);
576
+ Result->SetStringField(TEXT("note"), TEXT("For complex Niagara graph editing, use editor.execute_python with Niagara scripting APIs."));
577
+ return MakeShared<FJsonValueObject>(Result);
578
+ }
579
+
580
+ TSharedPtr<FJsonValue> FNiagaraHandlers::GetEmitterInfo(const TSharedPtr<FJsonObject>& Params)
581
+ {
582
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
583
+ FString AssetPath;
584
+ if (!Params->TryGetStringField(TEXT("assetPath"), AssetPath))
585
+ {
586
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'assetPath' parameter"));
587
+ return MakeShared<FJsonValueObject>(Result);
588
+ }
589
+
590
+ UNiagaraEmitter* Emitter = Cast<UNiagaraEmitter>(UEditorAssetLibrary::LoadAsset(AssetPath));
591
+ if (!Emitter)
592
+ {
593
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("NiagaraEmitter not found: %s"), *AssetPath));
594
+ return MakeShared<FJsonValueObject>(Result);
595
+ }
596
+
597
+ Result->SetStringField(TEXT("path"), AssetPath);
598
+ Result->SetStringField(TEXT("name"), Emitter->GetName());
599
+ Result->SetStringField(TEXT("class"), Emitter->GetClass()->GetName());
600
+ return MakeShared<FJsonValueObject>(Result);
601
+ }
@@ -0,0 +1,25 @@
1
+ #pragma once
2
+
3
+ #include "CoreMinimal.h"
4
+ #include "Dom/JsonValue.h"
5
+ #include "Dom/JsonObject.h"
6
+
7
+ class FNiagaraHandlers
8
+ {
9
+ public:
10
+ static void RegisterHandlers(class FMCPHandlerRegistry& Registry);
11
+
12
+ private:
13
+ static TSharedPtr<FJsonValue> ListNiagaraSystems(const TSharedPtr<FJsonObject>& Params);
14
+ static TSharedPtr<FJsonValue> ListNiagaraModules(const TSharedPtr<FJsonObject>& Params);
15
+ static TSharedPtr<FJsonValue> CreateNiagaraSystem(const TSharedPtr<FJsonObject>& Params);
16
+ static TSharedPtr<FJsonValue> GetNiagaraInfo(const TSharedPtr<FJsonObject>& Params);
17
+ static TSharedPtr<FJsonValue> ListEmittersInSystem(const TSharedPtr<FJsonObject>& Params);
18
+ static TSharedPtr<FJsonValue> CreateNiagaraEmitter(const TSharedPtr<FJsonObject>& Params);
19
+ static TSharedPtr<FJsonValue> SpawnNiagaraAtLocation(const TSharedPtr<FJsonObject>& Params);
20
+ static TSharedPtr<FJsonValue> SetNiagaraParameter(const TSharedPtr<FJsonObject>& Params);
21
+ static TSharedPtr<FJsonValue> CreateNiagaraSystemFromEmitter(const TSharedPtr<FJsonObject>& Params);
22
+ static TSharedPtr<FJsonValue> AddEmitterToSystem(const TSharedPtr<FJsonObject>& Params);
23
+ static TSharedPtr<FJsonValue> SetEmitterProperty(const TSharedPtr<FJsonObject>& Params);
24
+ static TSharedPtr<FJsonValue> GetEmitterInfo(const TSharedPtr<FJsonObject>& Params);
25
+ };