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,426 @@
1
+ #include "SequencerHandlers.h"
2
+ #include "HandlerRegistry.h"
3
+ #include "LevelSequence.h"
4
+ #include "LevelSequenceActor.h"
5
+ // LevelSequenceFactoryNew may not be available; use AssetTools directly
6
+ #include "MovieScene.h"
7
+ #include "MovieSceneTrack.h"
8
+ #include "MovieSceneSection.h"
9
+ #include "Tracks/MovieSceneFloatTrack.h"
10
+ #include "Tracks/MovieScene3DTransformTrack.h"
11
+ #include "Tracks/MovieSceneSkeletalAnimationTrack.h"
12
+ #include "Tracks/MovieSceneCameraCutTrack.h"
13
+ #include "Tracks/MovieSceneAudioTrack.h"
14
+ #include "Tracks/MovieSceneEventTrack.h"
15
+ #include "Tracks/MovieSceneFadeTrack.h"
16
+ #include "AssetRegistry/AssetRegistryModule.h"
17
+ #include "EditorScriptingUtilities/Public/EditorAssetLibrary.h"
18
+ #include "UObject/Package.h"
19
+ #include "Editor.h"
20
+ #include "Engine/World.h"
21
+ #include "EngineUtils.h"
22
+ #include "GameFramework/Actor.h"
23
+ #include "Dom/JsonObject.h"
24
+ #include "Dom/JsonValue.h"
25
+
26
+ void FSequencerHandlers::RegisterHandlers(FMCPHandlerRegistry& Registry)
27
+ {
28
+ Registry.RegisterHandler(TEXT("create_level_sequence"), &CreateLevelSequence);
29
+ Registry.RegisterHandler(TEXT("read_sequence_info"), &ReadSequenceInfo);
30
+ Registry.RegisterHandler(TEXT("add_track"), &AddTrack);
31
+ Registry.RegisterHandler(TEXT("sequence_control"), &SequenceControl);
32
+
33
+ // Aliases
34
+ Registry.RegisterHandler(TEXT("get_sequence_info"), &ReadSequenceInfo);
35
+ Registry.RegisterHandler(TEXT("add_sequence_track"), &AddTrack);
36
+ Registry.RegisterHandler(TEXT("play_sequence"), &SequenceControl);
37
+ }
38
+
39
+ TSharedPtr<FJsonValue> FSequencerHandlers::CreateLevelSequence(const TSharedPtr<FJsonObject>& Params)
40
+ {
41
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
42
+
43
+ FString Name;
44
+ if (!Params->TryGetStringField(TEXT("name"), Name))
45
+ {
46
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'name' parameter"));
47
+ Result->SetBoolField(TEXT("success"), false);
48
+ return MakeShared<FJsonValueObject>(Result);
49
+ }
50
+
51
+ FString PackagePath = TEXT("/Game/Cinematics");
52
+ Params->TryGetStringField(TEXT("packagePath"), PackagePath);
53
+
54
+ // Create the package
55
+ FString FullPackagePath = PackagePath / Name;
56
+ UPackage* Package = CreatePackage(*FullPackagePath);
57
+ if (!Package)
58
+ {
59
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to create package at '%s'"), *FullPackagePath));
60
+ Result->SetBoolField(TEXT("success"), false);
61
+ return MakeShared<FJsonValueObject>(Result);
62
+ }
63
+
64
+ // Create the level sequence asset
65
+ ULevelSequence* NewSequence = NewObject<ULevelSequence>(Package, FName(*Name), RF_Public | RF_Standalone);
66
+ NewSequence->Initialize();
67
+
68
+ if (!NewSequence)
69
+ {
70
+ Result->SetStringField(TEXT("error"), TEXT("Failed to create LevelSequence asset"));
71
+ Result->SetBoolField(TEXT("success"), false);
72
+ return MakeShared<FJsonValueObject>(Result);
73
+ }
74
+
75
+ // Notify the asset registry
76
+ FAssetRegistryModule::AssetCreated(NewSequence);
77
+
78
+ // Mark package dirty so it can be saved
79
+ Package->MarkPackageDirty();
80
+
81
+ Result->SetStringField(TEXT("name"), Name);
82
+ Result->SetStringField(TEXT("path"), NewSequence->GetPathName());
83
+ Result->SetStringField(TEXT("packagePath"), FullPackagePath);
84
+ Result->SetBoolField(TEXT("success"), true);
85
+
86
+ return MakeShared<FJsonValueObject>(Result);
87
+ }
88
+
89
+ TSharedPtr<FJsonValue> FSequencerHandlers::ReadSequenceInfo(const TSharedPtr<FJsonObject>& Params)
90
+ {
91
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
92
+
93
+ FString AssetPath;
94
+ if (!Params->TryGetStringField(TEXT("assetPath"), AssetPath) && !Params->TryGetStringField(TEXT("path"), AssetPath))
95
+ {
96
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'path' or 'assetPath' parameter"));
97
+ Result->SetBoolField(TEXT("success"), false);
98
+ return MakeShared<FJsonValueObject>(Result);
99
+ }
100
+
101
+ UObject* LoadedAsset = UEditorAssetLibrary::LoadAsset(AssetPath);
102
+ ULevelSequence* Sequence = Cast<ULevelSequence>(LoadedAsset);
103
+ if (!Sequence)
104
+ {
105
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to load LevelSequence at '%s'"), *AssetPath));
106
+ Result->SetBoolField(TEXT("success"), false);
107
+ return MakeShared<FJsonValueObject>(Result);
108
+ }
109
+
110
+ UMovieScene* MovieScene = Sequence->GetMovieScene();
111
+ if (!MovieScene)
112
+ {
113
+ Result->SetStringField(TEXT("error"), TEXT("LevelSequence has no MovieScene"));
114
+ Result->SetBoolField(TEXT("success"), false);
115
+ return MakeShared<FJsonValueObject>(Result);
116
+ }
117
+
118
+ Result->SetStringField(TEXT("name"), Sequence->GetName());
119
+ Result->SetStringField(TEXT("path"), Sequence->GetPathName());
120
+
121
+ // Display rate
122
+ FFrameRate DisplayRate = MovieScene->GetDisplayRate();
123
+ TSharedPtr<FJsonObject> DisplayRateObj = MakeShared<FJsonObject>();
124
+ DisplayRateObj->SetNumberField(TEXT("numerator"), DisplayRate.Numerator);
125
+ DisplayRateObj->SetNumberField(TEXT("denominator"), DisplayRate.Denominator);
126
+ Result->SetObjectField(TEXT("displayRate"), DisplayRateObj);
127
+
128
+ // Playback range
129
+ TRange<FFrameNumber> PlaybackRange = MovieScene->GetPlaybackRange();
130
+ TSharedPtr<FJsonObject> RangeObj = MakeShared<FJsonObject>();
131
+ if (PlaybackRange.HasLowerBound())
132
+ {
133
+ RangeObj->SetNumberField(TEXT("startFrame"), PlaybackRange.GetLowerBoundValue().Value);
134
+ }
135
+ if (PlaybackRange.HasUpperBound())
136
+ {
137
+ RangeObj->SetNumberField(TEXT("endFrame"), PlaybackRange.GetUpperBoundValue().Value);
138
+ }
139
+ Result->SetObjectField(TEXT("playbackRange"), RangeObj);
140
+
141
+ // Bindings (possessables and spawnables)
142
+ TArray<TSharedPtr<FJsonValue>> BindingsArray;
143
+ for (int32 i = 0; i < MovieScene->GetPossessableCount(); ++i)
144
+ {
145
+ const FMovieScenePossessable& Possessable = MovieScene->GetPossessable(i);
146
+ TSharedPtr<FJsonObject> BindingObj = MakeShared<FJsonObject>();
147
+ BindingObj->SetStringField(TEXT("name"), Possessable.GetName());
148
+ BindingObj->SetStringField(TEXT("guid"), Possessable.GetGuid().ToString());
149
+ BindingObj->SetStringField(TEXT("type"), TEXT("possessable"));
150
+
151
+ // List tracks for this binding
152
+ TArray<TSharedPtr<FJsonValue>> TrackNames;
153
+ const FMovieSceneBinding* Binding = MovieScene->FindBinding(Possessable.GetGuid());
154
+ if (Binding)
155
+ {
156
+ for (UMovieSceneTrack* Track : Binding->GetTracks())
157
+ {
158
+ if (Track)
159
+ {
160
+ TrackNames.Add(MakeShared<FJsonValueString>(Track->GetClass()->GetName()));
161
+ }
162
+ }
163
+ }
164
+ BindingObj->SetArrayField(TEXT("tracks"), TrackNames);
165
+
166
+ BindingsArray.Add(MakeShared<FJsonValueObject>(BindingObj));
167
+ }
168
+
169
+ for (int32 i = 0; i < MovieScene->GetSpawnableCount(); ++i)
170
+ {
171
+ const FMovieSceneSpawnable& Spawnable = MovieScene->GetSpawnable(i);
172
+ TSharedPtr<FJsonObject> BindingObj = MakeShared<FJsonObject>();
173
+ BindingObj->SetStringField(TEXT("name"), Spawnable.GetName());
174
+ BindingObj->SetStringField(TEXT("guid"), Spawnable.GetGuid().ToString());
175
+ BindingObj->SetStringField(TEXT("type"), TEXT("spawnable"));
176
+
177
+ TArray<TSharedPtr<FJsonValue>> TrackNames;
178
+ const FMovieSceneBinding* Binding = MovieScene->FindBinding(Spawnable.GetGuid());
179
+ if (Binding)
180
+ {
181
+ for (UMovieSceneTrack* Track : Binding->GetTracks())
182
+ {
183
+ if (Track)
184
+ {
185
+ TrackNames.Add(MakeShared<FJsonValueString>(Track->GetClass()->GetName()));
186
+ }
187
+ }
188
+ }
189
+ BindingObj->SetArrayField(TEXT("tracks"), TrackNames);
190
+
191
+ BindingsArray.Add(MakeShared<FJsonValueObject>(BindingObj));
192
+ }
193
+ Result->SetArrayField(TEXT("bindings"), BindingsArray);
194
+ Result->SetNumberField(TEXT("bindingCount"), BindingsArray.Num());
195
+
196
+ // Master tracks
197
+ TArray<TSharedPtr<FJsonValue>> MasterTracksArray;
198
+ for (UMovieSceneTrack* Track : MovieScene->GetTracks())
199
+ {
200
+ if (!Track) continue;
201
+ TSharedPtr<FJsonObject> TrackObj = MakeShared<FJsonObject>();
202
+ TrackObj->SetStringField(TEXT("name"), Track->GetTrackName().ToString());
203
+ TrackObj->SetStringField(TEXT("class"), Track->GetClass()->GetName());
204
+ TrackObj->SetNumberField(TEXT("sectionCount"), Track->GetAllSections().Num());
205
+ MasterTracksArray.Add(MakeShared<FJsonValueObject>(TrackObj));
206
+ }
207
+ Result->SetArrayField(TEXT("masterTracks"), MasterTracksArray);
208
+ Result->SetNumberField(TEXT("masterTrackCount"), MasterTracksArray.Num());
209
+
210
+ Result->SetBoolField(TEXT("success"), true);
211
+
212
+ return MakeShared<FJsonValueObject>(Result);
213
+ }
214
+
215
+ TSharedPtr<FJsonValue> FSequencerHandlers::AddTrack(const TSharedPtr<FJsonObject>& Params)
216
+ {
217
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
218
+
219
+ FString AssetPath;
220
+ if (!Params->TryGetStringField(TEXT("assetPath"), AssetPath) && !Params->TryGetStringField(TEXT("path"), AssetPath))
221
+ {
222
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'path' or 'assetPath' parameter"));
223
+ Result->SetBoolField(TEXT("success"), false);
224
+ return MakeShared<FJsonValueObject>(Result);
225
+ }
226
+
227
+ FString TrackType;
228
+ if (!Params->TryGetStringField(TEXT("trackType"), TrackType))
229
+ {
230
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'trackType' parameter (e.g. Transform, Float, SkeletalAnimation, CameraCut, Audio, Event, Fade)"));
231
+ Result->SetBoolField(TEXT("success"), false);
232
+ return MakeShared<FJsonValueObject>(Result);
233
+ }
234
+
235
+ UObject* LoadedAsset = UEditorAssetLibrary::LoadAsset(AssetPath);
236
+ ULevelSequence* Sequence = Cast<ULevelSequence>(LoadedAsset);
237
+ if (!Sequence)
238
+ {
239
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to load LevelSequence at '%s'"), *AssetPath));
240
+ Result->SetBoolField(TEXT("success"), false);
241
+ return MakeShared<FJsonValueObject>(Result);
242
+ }
243
+
244
+ UMovieScene* MovieScene = Sequence->GetMovieScene();
245
+ if (!MovieScene)
246
+ {
247
+ Result->SetStringField(TEXT("error"), TEXT("LevelSequence has no MovieScene"));
248
+ Result->SetBoolField(TEXT("success"), false);
249
+ return MakeShared<FJsonValueObject>(Result);
250
+ }
251
+
252
+ // Determine track class from type name
253
+ UClass* TrackClass = nullptr;
254
+ if (TrackType.Equals(TEXT("Transform"), ESearchCase::IgnoreCase))
255
+ {
256
+ TrackClass = UMovieScene3DTransformTrack::StaticClass();
257
+ }
258
+ else if (TrackType.Equals(TEXT("Float"), ESearchCase::IgnoreCase))
259
+ {
260
+ TrackClass = UMovieSceneFloatTrack::StaticClass();
261
+ }
262
+ else if (TrackType.Equals(TEXT("SkeletalAnimation"), ESearchCase::IgnoreCase))
263
+ {
264
+ TrackClass = UMovieSceneSkeletalAnimationTrack::StaticClass();
265
+ }
266
+ else if (TrackType.Equals(TEXT("CameraCut"), ESearchCase::IgnoreCase))
267
+ {
268
+ TrackClass = UMovieSceneCameraCutTrack::StaticClass();
269
+ }
270
+ else if (TrackType.Equals(TEXT("Audio"), ESearchCase::IgnoreCase))
271
+ {
272
+ TrackClass = UMovieSceneAudioTrack::StaticClass();
273
+ }
274
+ else if (TrackType.Equals(TEXT("Event"), ESearchCase::IgnoreCase))
275
+ {
276
+ TrackClass = UMovieSceneEventTrack::StaticClass();
277
+ }
278
+ else if (TrackType.Equals(TEXT("Fade"), ESearchCase::IgnoreCase))
279
+ {
280
+ TrackClass = UMovieSceneFadeTrack::StaticClass();
281
+ }
282
+ else
283
+ {
284
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Unknown track type: '%s'. Use Transform, Float, SkeletalAnimation, CameraCut, Audio, Event, or Fade."), *TrackType));
285
+ Result->SetBoolField(TEXT("success"), false);
286
+ return MakeShared<FJsonValueObject>(Result);
287
+ }
288
+
289
+ // Check if we should add to an actor binding or as a master track
290
+ FString ActorLabel;
291
+ if (Params->TryGetStringField(TEXT("actorLabel"), ActorLabel) && !ActorLabel.IsEmpty())
292
+ {
293
+ // Find the binding for this actor
294
+ UWorld* World = GEditor->GetEditorWorldContext().World();
295
+ if (!World)
296
+ {
297
+ Result->SetStringField(TEXT("error"), TEXT("Editor world not available"));
298
+ Result->SetBoolField(TEXT("success"), false);
299
+ return MakeShared<FJsonValueObject>(Result);
300
+ }
301
+
302
+ // Find actor by label
303
+ AActor* TargetActor = nullptr;
304
+ for (TActorIterator<AActor> ActorIt(World); ActorIt; ++ActorIt)
305
+ {
306
+ if ((*ActorIt)->GetActorLabel() == ActorLabel)
307
+ {
308
+ TargetActor = *ActorIt;
309
+ break;
310
+ }
311
+ }
312
+
313
+ if (!TargetActor)
314
+ {
315
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Actor not found: %s"), *ActorLabel));
316
+ Result->SetBoolField(TEXT("success"), false);
317
+ return MakeShared<FJsonValueObject>(Result);
318
+ }
319
+
320
+ // Find or create a binding for this actor
321
+ FGuid BindingGuid;
322
+ bool bFoundBinding = false;
323
+
324
+ // Search existing possessables
325
+ for (int32 i = 0; i < MovieScene->GetPossessableCount(); ++i)
326
+ {
327
+ const FMovieScenePossessable& Possessable = MovieScene->GetPossessable(i);
328
+ if (Possessable.GetName() == ActorLabel || Possessable.GetName() == TargetActor->GetName())
329
+ {
330
+ BindingGuid = Possessable.GetGuid();
331
+ bFoundBinding = true;
332
+ break;
333
+ }
334
+ }
335
+
336
+ if (!bFoundBinding)
337
+ {
338
+ // Create a new possessable binding for the actor
339
+ BindingGuid = MovieScene->AddPossessable(ActorLabel, TargetActor->GetClass());
340
+ Sequence->BindPossessableObject(BindingGuid, *TargetActor, World);
341
+ }
342
+
343
+ // Add track to binding
344
+ UMovieSceneTrack* NewTrack = MovieScene->AddTrack(TrackClass, BindingGuid);
345
+ if (!NewTrack)
346
+ {
347
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to add %s track to actor '%s'"), *TrackType, *ActorLabel));
348
+ Result->SetBoolField(TEXT("success"), false);
349
+ return MakeShared<FJsonValueObject>(Result);
350
+ }
351
+
352
+ Result->SetStringField(TEXT("actorLabel"), ActorLabel);
353
+ Result->SetStringField(TEXT("bindingGuid"), BindingGuid.ToString());
354
+ Result->SetStringField(TEXT("trackType"), TrackType);
355
+ Result->SetStringField(TEXT("trackClass"), NewTrack->GetClass()->GetName());
356
+ Result->SetStringField(TEXT("scope"), TEXT("binding"));
357
+ Result->SetBoolField(TEXT("success"), true);
358
+ }
359
+ else
360
+ {
361
+ // Add as master track
362
+ UMovieSceneTrack* NewTrack = MovieScene->AddTrack(TrackClass);
363
+ if (!NewTrack)
364
+ {
365
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Failed to add master %s track"), *TrackType));
366
+ Result->SetBoolField(TEXT("success"), false);
367
+ return MakeShared<FJsonValueObject>(Result);
368
+ }
369
+
370
+ Result->SetStringField(TEXT("trackType"), TrackType);
371
+ Result->SetStringField(TEXT("trackClass"), NewTrack->GetClass()->GetName());
372
+ Result->SetStringField(TEXT("scope"), TEXT("master"));
373
+ Result->SetBoolField(TEXT("success"), true);
374
+ }
375
+
376
+ // Mark the sequence package dirty
377
+ Sequence->GetOutermost()->MarkPackageDirty();
378
+
379
+ return MakeShared<FJsonValueObject>(Result);
380
+ }
381
+
382
+ TSharedPtr<FJsonValue> FSequencerHandlers::SequenceControl(const TSharedPtr<FJsonObject>& Params)
383
+ {
384
+ TSharedPtr<FJsonObject> Result = MakeShared<FJsonObject>();
385
+
386
+ FString Action;
387
+ if (!Params->TryGetStringField(TEXT("action"), Action))
388
+ {
389
+ Result->SetStringField(TEXT("error"), TEXT("Missing 'action' parameter (play, pause, stop)"));
390
+ Result->SetBoolField(TEXT("success"), false);
391
+ return MakeShared<FJsonValueObject>(Result);
392
+ }
393
+
394
+ FString Command;
395
+ if (Action.Equals(TEXT("play"), ESearchCase::IgnoreCase))
396
+ {
397
+ Command = TEXT("Sequencer.Play");
398
+ }
399
+ else if (Action.Equals(TEXT("pause"), ESearchCase::IgnoreCase))
400
+ {
401
+ Command = TEXT("Sequencer.Pause");
402
+ }
403
+ else if (Action.Equals(TEXT("stop"), ESearchCase::IgnoreCase))
404
+ {
405
+ Command = TEXT("Sequencer.Stop");
406
+ }
407
+ else
408
+ {
409
+ Result->SetStringField(TEXT("error"), FString::Printf(TEXT("Unknown action: '%s'. Use play, pause, or stop."), *Action));
410
+ Result->SetBoolField(TEXT("success"), false);
411
+ return MakeShared<FJsonValueObject>(Result);
412
+ }
413
+
414
+ // Execute via console command
415
+ UWorld* World = GEditor->GetEditorWorldContext().World();
416
+ if (World)
417
+ {
418
+ GEditor->Exec(World, *Command, *GLog);
419
+ }
420
+
421
+ Result->SetStringField(TEXT("action"), Action);
422
+ Result->SetStringField(TEXT("command"), Command);
423
+ Result->SetBoolField(TEXT("success"), true);
424
+
425
+ return MakeShared<FJsonValueObject>(Result);
426
+ }
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include "CoreMinimal.h"
4
+ #include "Dom/JsonValue.h"
5
+ #include "Dom/JsonObject.h"
6
+
7
+ class FSequencerHandlers
8
+ {
9
+ public:
10
+ // Register all sequencer handlers
11
+ static void RegisterHandlers(class FMCPHandlerRegistry& Registry);
12
+
13
+ private:
14
+ // Handler implementations
15
+ static TSharedPtr<FJsonValue> CreateLevelSequence(const TSharedPtr<FJsonObject>& Params);
16
+ static TSharedPtr<FJsonValue> ReadSequenceInfo(const TSharedPtr<FJsonObject>& Params);
17
+ static TSharedPtr<FJsonValue> AddTrack(const TSharedPtr<FJsonObject>& Params);
18
+ static TSharedPtr<FJsonValue> SequenceControl(const TSharedPtr<FJsonObject>& Params);
19
+ };