claude-code-arcane 2.3.0 → 2.5.0

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/CHANGELOG.md +23 -0
  2. package/README.md +131 -41
  3. package/agents/game/ue-blueprint-specialist.md +125 -0
  4. package/agents/game/ue-gas-specialist.md +133 -0
  5. package/agents/game/ue-umg-specialist.md +131 -0
  6. package/dist/cli.js +642 -478
  7. package/docs/SKILLS-CATALOG.md +42 -3
  8. package/docs/USER-GUIDE.md +28 -54
  9. package/hooks/detect-unreal.sh +90 -0
  10. package/package.json +2 -1
  11. package/profiles/agile.yaml +1 -1
  12. package/profiles/ai.yaml +1 -1
  13. package/profiles/android-native.yaml +1 -1
  14. package/profiles/audio.yaml +1 -1
  15. package/profiles/backend-dotnet.yaml +1 -1
  16. package/profiles/backend-go.yaml +1 -1
  17. package/profiles/backend-nestjs.yaml +1 -1
  18. package/profiles/backend-nextjs.yaml +1 -1
  19. package/profiles/backend-ts.yaml +1 -1
  20. package/profiles/business.yaml +1 -1
  21. package/profiles/clevel.yaml +1 -1
  22. package/profiles/clickup.yaml +1 -1
  23. package/profiles/core.yaml +1 -1
  24. package/profiles/database.yaml +1 -1
  25. package/profiles/design.yaml +1 -1
  26. package/profiles/docs.yaml +1 -1
  27. package/profiles/ecommerce.yaml +1 -1
  28. package/profiles/finance.yaml +1 -1
  29. package/profiles/flutter.yaml +1 -1
  30. package/profiles/freelance.yaml +1 -1
  31. package/profiles/frontend.yaml +1 -1
  32. package/profiles/infra.yaml +1 -1
  33. package/profiles/integrations.yaml +1 -1
  34. package/profiles/ios-native.yaml +1 -1
  35. package/profiles/jira.yaml +1 -1
  36. package/profiles/job-hunt.yaml +1 -1
  37. package/profiles/marketing.yaml +1 -1
  38. package/profiles/mobile.yaml +1 -1
  39. package/profiles/regulatory.yaml +1 -1
  40. package/profiles/second-brain.yaml +1 -1
  41. package/profiles/security.yaml +1 -1
  42. package/profiles/self-improving.yaml +1 -1
  43. package/profiles/statusline.yaml +1 -1
  44. package/profiles/testing.yaml +1 -1
  45. package/profiles/unity-design.yaml +1 -1
  46. package/profiles/unity-dev.yaml +1 -1
  47. package/profiles/unreal-dev.yaml +97 -0
  48. package/profiles/visual-novel.yaml +1 -1
  49. package/rules/gamedev/unreal-code.md +125 -0
  50. package/skills/arcane-list/SKILL.md +12 -7
  51. package/skills/install-mcp/SKILL.md +135 -46
  52. package/skills/install-mcp/references/unreal-operations.md +55 -0
  53. package/skills/ue-actor-component-architecture/SKILL.md +509 -0
  54. package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
  55. package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
  56. package/skills/ue-ai-navigation/SKILL.md +526 -0
  57. package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
  58. package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
  59. package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
  60. package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
  61. package/skills/ue-animation-system/SKILL.md +521 -0
  62. package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
  63. package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
  64. package/skills/ue-async-threading/SKILL.md +433 -0
  65. package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
  66. package/skills/ue-async-threading/references/threading-patterns.md +345 -0
  67. package/skills/ue-audio-system/SKILL.md +527 -0
  68. package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
  69. package/skills/ue-blueprints/SKILL.md +134 -0
  70. package/skills/ue-blueprints/references/communication.md +82 -0
  71. package/skills/ue-character-movement/SKILL.md +475 -0
  72. package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
  73. package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
  74. package/skills/ue-cpp-foundations/SKILL.md +533 -0
  75. package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
  76. package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
  77. package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
  78. package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
  79. package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
  80. package/skills/ue-data-assets-tables/SKILL.md +527 -0
  81. package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
  82. package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
  83. package/skills/ue-editor-tools/SKILL.md +523 -0
  84. package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
  85. package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
  86. package/skills/ue-game-features/SKILL.md +477 -0
  87. package/skills/ue-game-features/references/experience-system.md +222 -0
  88. package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
  89. package/skills/ue-gameplay-abilities/SKILL.md +518 -0
  90. package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
  91. package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
  92. package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
  93. package/skills/ue-gameplay-framework/SKILL.md +466 -0
  94. package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
  95. package/skills/ue-input-system/SKILL.md +394 -0
  96. package/skills/ue-input-system/references/cpp-setup.md +131 -0
  97. package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
  98. package/skills/ue-input-system/references/input-action-reference.md +731 -0
  99. package/skills/ue-mass-entity/SKILL.md +476 -0
  100. package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
  101. package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
  102. package/skills/ue-materials-rendering/SKILL.md +526 -0
  103. package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
  104. package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
  105. package/skills/ue-module-build-system/SKILL.md +487 -0
  106. package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
  107. package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
  108. package/skills/ue-naming-conventions/SKILL.md +142 -0
  109. package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
  110. package/skills/ue-naming-conventions/references/content-structure.md +83 -0
  111. package/skills/ue-networking-replication/SKILL.md +452 -0
  112. package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
  113. package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
  114. package/skills/ue-niagara-effects/SKILL.md +531 -0
  115. package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
  116. package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
  117. package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
  118. package/skills/ue-packaging/SKILL.md +116 -0
  119. package/skills/ue-physics-collision/SKILL.md +423 -0
  120. package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
  121. package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
  122. package/skills/ue-procedural-generation/SKILL.md +505 -0
  123. package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
  124. package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
  125. package/skills/ue-project-context/SKILL.md +305 -0
  126. package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
  127. package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
  128. package/skills/ue-serialization-savegames/SKILL.md +524 -0
  129. package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
  130. package/skills/ue-state-trees/SKILL.md +489 -0
  131. package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
  132. package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
  133. package/skills/ue-testing-debugging/SKILL.md +520 -0
  134. package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
  135. package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
  136. package/skills/ue-ui-umg-slate/SKILL.md +431 -0
  137. package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
  138. package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
  139. package/skills/ue-world-level-streaming/SKILL.md +518 -0
  140. package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
  141. package/templates/gamedev/unreal-project-context.md +107 -0
@@ -0,0 +1,506 @@
1
+ ---
2
+ name: ue-sequencer-cinematics
3
+ description: "Sequencer, LevelSequence, cutscenes, cinematics, camera tracks, Movie Render Queue"
4
+ category: "gamedev"
5
+ argument-hint: "[sequence o shot]"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep, Bash, Write, Edit
8
+ ---
9
+
10
+ # Skill: ue-sequencer-cinematics
11
+
12
+ You are an expert in Unreal Engine's Sequencer and cinematic systems.
13
+
14
+ Ask before writing: this skill edits LevelSequence assets and sequencer-driving code. Propose the change and get approval before using Write or Edit.
15
+
16
+ ## Context Check
17
+
18
+ Read `docs/unreal/project-context.md` before writing any cinematic code for:
19
+ - Target UE version (API availability varies — SequencePlayer property deprecated in 5.4+)
20
+ - Cinematic requirements (cutscenes, in-game cameras, offline rendering)
21
+ - Multiplayer context (sequence replication behavior differs)
22
+ - Build.cs modules already declared
23
+
24
+ ## Information Gathering
25
+
26
+ Ask for:
27
+ 1. Cinematic type: full-screen cutscene, in-game camera, or background ambient sequence
28
+ 2. Whether actors bind at runtime or are pre-placed in the level
29
+ 3. Whether camera control must return to the player after playback
30
+ 4. One-shot or looping sequence
31
+ 5. Real-time gameplay or offline Movie Render Queue output
32
+
33
+ ---
34
+
35
+ ## Build.cs Modules
36
+
37
+ ```csharp
38
+ PublicDependencyModuleNames.AddRange(new string[]
39
+ {
40
+ "LevelSequence", "MovieScene", "CinematicCamera",
41
+ });
42
+ // Offline rendering only:
43
+ PrivateDependencyModuleNames.Add("MovieRenderPipelineCore");
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Playing Level Sequences
49
+
50
+ ### ALevelSequenceActor — World-Placed
51
+
52
+ `ALevelSequenceActor` owns the player. Use `GetSequencePlayer()` — the direct `SequencePlayer`
53
+ property is deprecated since UE 5.4.
54
+
55
+ ```cpp
56
+ // LevelSequenceActor.h: ULevelSequencePlayer* GetSequencePlayer() const;
57
+ ULevelSequencePlayer* Player = SeqActor->GetSequencePlayer();
58
+ if (Player) { Player->Play(); }
59
+ ```
60
+
61
+ ### ULevelSequencePlayer::CreateLevelSequencePlayer — Runtime Spawn
62
+
63
+ ```cpp
64
+ // LevelSequencePlayer.h:
65
+ // static ULevelSequencePlayer* CreateLevelSequencePlayer(
66
+ // UObject* WorldContextObject, ULevelSequence*, FMovieSceneSequencePlaybackSettings,
67
+ // ALevelSequenceActor*& OutActor);
68
+
69
+ FMovieSceneSequencePlaybackSettings Settings;
70
+ Settings.bAutoPlay = false;
71
+ Settings.PlayRate = 1.0f;
72
+ Settings.LoopCount.Value = 0; // 0=once, -1=infinite
73
+ Settings.bDisableMovementInput = true;
74
+ Settings.bDisableLookAtInput = true;
75
+ Settings.bHidePlayer = false;
76
+ Settings.bHideHud = false;
77
+ Settings.bDisableCameraCuts = false;
78
+ Settings.bPauseAtEnd = false;
79
+ Settings.FinishCompletionStateOverride =
80
+ EMovieSceneCompletionModeOverride::ForceRestoreState; // safe for skippable cutscenes
81
+
82
+ ALevelSequenceActor* OutActor = nullptr;
83
+ ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(
84
+ this, Sequence, Settings, OutActor);
85
+
86
+ // Store OutActor in a UPROPERTY to prevent GC
87
+ ActiveSequenceActor = OutActor;
88
+
89
+ if (Player)
90
+ {
91
+ Player->OnFinished.AddDynamic(this, &AMyClass::OnCutsceneFinished);
92
+ Player->Play();
93
+ }
94
+ ```
95
+
96
+ ### Play Control (UMovieSceneSequencePlayer base)
97
+
98
+ ```cpp
99
+ // MovieSceneSequencePlayer.h
100
+ Player->Play();
101
+ Player->PlayReverse();
102
+ Player->PlayLooping(-1); // -1 = infinite loops
103
+ Player->Pause();
104
+ Player->Stop(); // moves cursor to end, fires OnStop
105
+ Player->StopAtCurrentTime();
106
+ Player->GoToEndAndStop();
107
+ Player->SetPlayRate(0.5f); // negative = reverse
108
+
109
+ // Jump to frame (skips events between current and target)
110
+ // Blueprint exposes this as GoToFrame. In C++, use SetPlaybackPosition with Jump.
111
+ Player->SetPlaybackPosition(
112
+ FMovieSceneSequencePlaybackParams(FFrameTime(120), EUpdatePositionMethod::Jump));
113
+
114
+ // Play through to frame (triggers all events along the way)
115
+ Player->PlayTo(
116
+ FMovieSceneSequencePlaybackParams(FFrameTime(240), EUpdatePositionMethod::Play),
117
+ FMovieSceneSequencePlayToParams());
118
+
119
+ // Restrict play range
120
+ Player->SetFrameRange(0, 60); // frames 0–60
121
+ Player->SetTimeRange(0.0f, 2.5f); // seconds
122
+
123
+ // State query
124
+ bool bPlaying = Player->IsPlaying();
125
+ FQualifiedFrameTime Now = Player->GetCurrentTime();
126
+ FQualifiedFrameTime Dur = Player->GetDuration();
127
+
128
+ // Delegates (bind before Play)
129
+ Player->OnFinished.AddDynamic(this, &UMyClass::OnSeqFinished);
130
+ Player->OnPlay.AddDynamic(this, &UMyClass::OnSeqPlay);
131
+ Player->OnStop.AddDynamic(this, &UMyClass::OnSeqStop);
132
+ Player->OnNativeFinished.BindUObject(this, &UMyClass::OnNativeFinished); // non-dynamic
133
+
134
+ // Camera cut event (LevelSequencePlayer.h)
135
+ // DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnLevelSequencePlayerCameraCutEvent, UCameraComponent*, CameraComponent)
136
+ LsPlayer->OnCameraCut.AddDynamic(this, &UMyClass::OnCameraCut);
137
+
138
+ // Restore state on early stop (skippable cutscene)
139
+ Player->SetCompletionModeOverride(EMovieSceneCompletionModeOverride::ForceRestoreState);
140
+ Player->Stop();
141
+
142
+ // Sub-sequence snapshot
143
+ FLevelSequencePlayerSnapshot Snap;
144
+ Player->TakeFrameSnapshot(Snap);
145
+ // Snap.CurrentShotName, Snap.RootTime, Snap.CameraComponent, Snap.ActiveShot
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Actor Binding
151
+
152
+ Tag bindings in Sequencer (right-click object binding -> Tags...) then override at runtime.
153
+ **Always bind before calling `Play()`.**
154
+
155
+ ### Spawnables vs Possessables
156
+
157
+ **Possessables** bind to pre-existing world actors (placed in level or spawned by gameplay). **Spawnables** are actors the sequence itself creates and destroys.
158
+
159
+ ```cpp
160
+ // Spawnable: sequence owns the actor lifecycle
161
+ // Set in Sequencer editor: right-click actor track → "Change to Spawnable"
162
+ // At runtime, actor spawns when sequence reaches its range, despawns when exiting
163
+
164
+ // Dynamic possessable: bind a gameplay-spawned actor to a sequence track
165
+ // Create the binding ID in the editor, then override at runtime:
166
+ FMovieSceneObjectBindingID BindingID = /* from sequence editor */;
167
+ ALevelSequenceActor* SeqActor = /* your sequence actor */;
168
+ SeqActor->SetBinding(BindingID, {SpawnedActor});
169
+ ```
170
+
171
+ **Why this matters**: Use possessables for persistent world actors (doors, elevators) and spawnables for transient cutscene-only actors (cinematic-only characters, props). Possessables survive sequence end; spawnables are cleaned up automatically.
172
+
173
+ ```cpp
174
+ // LevelSequenceActor.h — all binding API lives here
175
+
176
+ // Replace bound actors (preferred: tag-based, resilient to GUID changes)
177
+ SeqActor->SetBindingByTag(FName("Hero"), TArray<AActor*>{ HeroActor },
178
+ /*bAllowBindingsFromAsset=*/ false);
179
+
180
+ // GUID-based (expose FMovieSceneObjectBindingID via UPROPERTY for editor assignment)
181
+ // UPROPERTY(EditAnywhere) FMovieSceneObjectBindingID HeroBindingID;
182
+ SeqActor->SetBinding(HeroBindingID, TArray<AActor*>{ HeroActor }, false);
183
+
184
+ // Append without removing existing bindings
185
+ SeqActor->AddBindingByTag(FName("NPC"), NpcActor, /*bAllowBindingsFromAsset=*/ true);
186
+
187
+ // Remove / reset
188
+ SeqActor->RemoveBindingByTag(FName("NPC"), NpcActor);
189
+ SeqActor->ResetBinding(HeroBindingID); // revert to asset binding
190
+ SeqActor->ResetBindings(); // revert all overrides
191
+
192
+ // Lookup by tag
193
+ FMovieSceneObjectBindingID ID = SeqActor->FindNamedBinding(FName("Hero"));
194
+ const TArray<FMovieSceneObjectBindingID>& All = SeqActor->FindNamedBindings(FName("NPC"));
195
+
196
+ // Inspect what is currently bound
197
+ TArray<UObject*> Bound = Player->GetBoundObjects(HeroBindingID);
198
+
199
+ // FMovieSceneObjectBindingID (MovieSceneObjectBindingID.h):
200
+ // Access via public accessors — internal fields are private:
201
+ // GetGuid() — FGuid identifying the binding track
202
+ // GetRelativeSequenceID() — which sub-sequence holds it (0 = local)
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Camera System
208
+
209
+ ### ACineCameraActor / UCineCameraComponent
210
+
211
+ ```cpp
212
+ // CineCameraActor.h: UCineCameraComponent* GetCineCameraComponent() const;
213
+ // CineCameraComponent.h / CineCameraSettings.h:
214
+ // FCameraFilmbackSettings Filmback (SensorWidth, SensorHeight in mm, read-only SensorAspectRatio)
215
+ // FCameraLensSettings LensSettings (MinFocalLength, MaxFocalLength, MinFStop, MaxFStop mm)
216
+ // FCameraFocusSettings FocusSettings (FocusMethod, ManualFocusDistance cm, bSmoothFocusChanges)
217
+ // float CurrentFocalLength — Interp, animatable in Sequencer
218
+ // float CurrentAperture — f-stop, Interp-animatable
219
+
220
+ ACineCameraActor* Cam = GetWorld()->SpawnActor<ACineCameraActor>(SpawnTransform);
221
+ UCineCameraComponent* CC = Cam->GetCineCameraComponent();
222
+
223
+ FCameraFilmbackSettings FB;
224
+ FB.SensorWidth = 36.0f; FB.SensorHeight = 24.0f; // full-frame 35mm
225
+ CC->SetFilmback(FB);
226
+
227
+ CC->SetCurrentFocalLength(50.0f); // mm
228
+ CC->SetCurrentAperture(2.0f); // f-stop
229
+
230
+ FCameraFocusSettings FS;
231
+ FS.FocusMethod = ECameraFocusMethod::Manual; // Manual | Tracking | Disable | DoNotOverride
232
+ FS.ManualFocusDistance = 500.0f; // cm
233
+ FS.bSmoothFocusChanges = true;
234
+ CC->SetFocusSettings(FS);
235
+
236
+ // Lookat tracking (CineCameraActor.h: FCameraLookatTrackingSettings LookatTrackingSettings)
237
+ Cam->LookatTrackingSettings.bEnableLookAtTracking = true;
238
+ Cam->LookatTrackingSettings.ActorToTrack = TargetActor;
239
+ Cam->LookatTrackingSettings.LookAtTrackingInterpSpeed = 5.0f;
240
+ Cam->LookatTrackingSettings.RelativeOffset = FVector(0, 0, 90.f);
241
+
242
+ // Prevent sequence from overriding gameplay camera (set before Play)
243
+ SeqActor->PlaybackSettings.bDisableCameraCuts = true;
244
+
245
+ // Restore player camera after cutscene (call from OnFinished delegate)
246
+ APlayerController* PC = GetWorld()->GetFirstPlayerController();
247
+ PC->SetViewTargetWithBlend(PC->GetPawn(), 0.5f, VTBlend_Cubic);
248
+ PC->SetIgnoreMoveInput(false);
249
+ PC->SetIgnoreLookInput(false);
250
+ ```
251
+
252
+ ### APlayerCameraManager
253
+
254
+ `APlayerCameraManager` (accessed via `PlayerController->PlayerCameraManager`) manages camera
255
+ blending and view target selection for the local player. After a cutscene ends, restore the
256
+ gameplay camera explicitly — Sequencer does not do this automatically:
257
+
258
+ ```cpp
259
+ APlayerController* PC = GetWorld()->GetFirstPlayerController();
260
+ // PlayerCameraManager handles blend state; SetViewTargetWithBlend triggers it.
261
+ PC->SetViewTargetWithBlend(PC->GetPawn(), 0.5f, VTBlend_Cubic);
262
+ // The blend is processed each tick inside APlayerCameraManager::UpdateCamera.
263
+ ```
264
+
265
+ ---
266
+
267
+ ## Sequencer Events
268
+
269
+ Event tracks call `UFUNCTION`s on objects in the event context.
270
+ Default event context: `UWorld` + `ALevelScriptActor`.
271
+
272
+ ```cpp
273
+ // Function must be UFUNCTION(BlueprintCallable) on a context object
274
+ UFUNCTION(BlueprintCallable, Category = "Cinematics")
275
+ void TriggerExplosion()
276
+ {
277
+ ExplosionSystem->SpawnExplosion(ExplosionLocation);
278
+ }
279
+
280
+ // Trigger C++ code at a specific frame by playing to it (fires all events in range)
281
+ Player->PlayTo(
282
+ FMovieSceneSequencePlaybackParams(FFrameTime(60), EUpdatePositionMethod::Play),
283
+ FMovieSceneSequencePlayToParams());
284
+ ```
285
+
286
+ ### FMovieSceneEvent
287
+
288
+ `FMovieSceneEvent` holds the event endpoint data — the bound function to call when the event
289
+ fires. Event tracks are structured as:
290
+
291
+ - `UMovieSceneEventTrack` — the master track added to a binding or as a master track
292
+ - `UMovieSceneEventTriggerSection` — a section containing one or more trigger entries
293
+ - `FMovieSceneEvent` — each entry inside the trigger section, pointing to the endpoint function
294
+
295
+ The endpoint function is resolved at runtime against the event context objects (by default
296
+ `UWorld` and `ALevelScriptActor`). Director-based events resolve against a
297
+ `ULevelSequenceDirector` subclass instance.
298
+
299
+ ### ULevelSequenceDirector — Custom Event Context
300
+
301
+ `ULevelSequenceDirector` provides a per-sequence scripting context that receives event track
302
+ calls. Subclass it (Blueprint or C++) and assign to the LevelSequence asset's Director Class
303
+ property. The Director instance is created when the sequence begins playing and destroyed
304
+ when it stops — its lifetime matches the sequence player.
305
+
306
+ ```cpp
307
+ // MySequenceDirector.h
308
+ #include "LevelSequenceDirector.h"
309
+ #include "MySequenceDirector.generated.h"
310
+
311
+ UCLASS(Blueprintable)
312
+ class UMySequenceDirector : public ULevelSequenceDirector
313
+ {
314
+ GENERATED_BODY()
315
+ public:
316
+ // Called from Sequencer event tracks — bind to event key in the Sequencer editor
317
+ UFUNCTION(BlueprintCallable, Category = "Cinematics")
318
+ void OnDialogueStart(FName SpeakerTag);
319
+
320
+ UFUNCTION(BlueprintCallable, Category = "Cinematics")
321
+ void OnCutsceneChoice(int32 ChoiceIndex);
322
+ };
323
+
324
+ // MySequenceDirector.cpp
325
+ void UMySequenceDirector::OnDialogueStart(FName SpeakerTag)
326
+ {
327
+ // Access the sequence player and bound actors from within the Director.
328
+ // ULevelSequenceDirector.h: UPROPERTY ULevelSequencePlayer* Player (direct field, no getter)
329
+ TArray<UObject*> Bound = Player->GetBoundObjects(SpeakerBindingID);
330
+ // Trigger gameplay logic: UI, dialogue system, camera focus, etc.
331
+ }
332
+ ```
333
+
334
+ **Why Director over Level Script**: The Director travels with the sequence asset, not the level.
335
+ Reusable across maps. Supports per-sequence state (member variables). Level Script events
336
+ only work when the sequence is placed in that specific level.
337
+
338
+ ---
339
+
340
+ ## MovieScene Tracks
341
+
342
+ ```cpp
343
+ // MovieScene.h — get from the LevelSequence asset
344
+ UMovieScene* MS = SeqActor->GetSequence()->GetMovieScene();
345
+
346
+ // Possessables (world actors) — iterate by index
347
+ for (int32 i = 0; i < MS->GetPossessableCount(); ++i)
348
+ {
349
+ const FMovieScenePossessable& P = MS->GetPossessable(i);
350
+ }
351
+ // Spawnables (sequence-owned actors) — iterate by index
352
+ for (int32 i = 0; i < MS->GetSpawnableCount(); ++i)
353
+ {
354
+ const FMovieSceneSpawnable& S = MS->GetSpawnable(i);
355
+ }
356
+
357
+ // Master tracks (not bound to any actor)
358
+ const TArray<UMovieSceneTrack*>& Masters = MS->GetTracks();
359
+
360
+ // Tracks on a specific binding
361
+ const FMovieSceneBinding* B = MS->FindBinding(SomeGuid);
362
+ if (B) { for (UMovieSceneTrack* T : B->GetTracks()) { /* cast to subtype */ } }
363
+ ```
364
+
365
+ | Track Class | Purpose |
366
+ |---|---|
367
+ | `UMovieScene3DTransformTrack` | Transform animation |
368
+ | `UMovieSceneSkeletalAnimationTrack` | Skeletal mesh animation |
369
+ | `UMovieSceneEventTrack` | Event triggers |
370
+ | `UMovieSceneAudioTrack` | Audio |
371
+ | `UMovieSceneFadeTrack` | Screen fade |
372
+ | `UMovieSceneCameraCutTrack` | Camera cuts |
373
+ | `UMovieSceneSubTrack` | Sub-sequences |
374
+ | `UMovieScenePropertyTrack` | Arbitrary UPROPERTY animation (base class) |
375
+
376
+ All track types require `MovieSceneTracks` in Build.cs.
377
+
378
+ **Custom tracks**: subclass `UMovieSceneTrack` + `UMovieSceneSection` for domain-specific
379
+ animation data. Register via `ISequencerModule::RegisterTrackEditor`. This is an advanced
380
+ pattern — most needs are met by `UMovieScenePropertyTrack` subclasses.
381
+
382
+ `UMovieScenePropertyTrack` animates arbitrary `UPROPERTY` values on bound objects. Common
383
+ concrete subclasses: `UMovieSceneFloatTrack` (float properties), `UMovieSceneBoolTrack`
384
+ (bool properties), `UMovieSceneColorTrack` (FLinearColor / FColor properties). Each creates
385
+ sections of the matching type (e.g., `UMovieSceneFloatSection`) that store a `FMovieSceneFloatChannel`.
386
+
387
+ ### Sub-Sequences
388
+
389
+ ```cpp
390
+ // Add a sub-sequence track to a master UMovieScene
391
+ UMovieScene* MasterMS = MasterSequence->GetMovieScene();
392
+ UMovieSceneSubTrack* SubTrack = MasterMS->AddTrack<UMovieSceneSubTrack>();
393
+
394
+ // Add a child sequence — AddSequence(Sequence, StartFrame, Duration)
395
+ FFrameRate DisplayRate = MasterMS->GetDisplayRate();
396
+ FFrameNumber Start = (2.0 * DisplayRate).FloorToFrame(); // 2 seconds in
397
+ int32 Duration = (5.0 * DisplayRate).FloorToFrame().Value; // 5 seconds long
398
+ UMovieSceneSubSection* SubSection =
399
+ SubTrack->AddSequence(ChildLevelSequence, Start, Duration);
400
+
401
+ // Configure sub-section timing
402
+ SubSection->Parameters.TimeScale = 1.0; // FMovieSceneTimeWarpVariant (double), playback speed multiplier
403
+ SubSection->Parameters.bCanLoop = false;
404
+ ```
405
+
406
+ `UMovieSceneSubTrack` is a singleton master track — `AddTrack` returns the existing one if already present. Binding IDs inside sub-sequences carry a non-zero `SequenceID`; use `FMovieSceneObjectBindingID::ResolveParentIndex` when overriding bindings from the root player. Requires `MovieSceneTracks` module.
407
+
408
+ ### Time Dilation and SlowMo
409
+
410
+ For SlowMo effects during sequences, use `Player->SetPlayRate(0.5f)` on the sequence player —
411
+ this is independent of `UGameplayStatics::SetGlobalTimeDilation` and does not affect world
412
+ physics or other gameplay systems. Combine with a post-process motion blur intensity increase
413
+ for cinematic slow motion without disrupting gameplay state.
414
+
415
+ ---
416
+
417
+ ## Movie Render Queue
418
+
419
+ ```cpp
420
+ // MovieRenderPipelineCore module. Classes:
421
+ // UMoviePipelineQueue — holds jobs
422
+ // UMoviePipelineExecutorJob — sequence + map + config per job
423
+ // UMoviePipelinePrimaryConfig — root settings container
424
+ // UMoviePipelineOutputSetting — output path, file name format, frame rate
425
+ // Output formats: UMoviePipelineImageSequenceOutput_PNG / _EXR, UMoviePipelineAppleProResOutput
426
+ // Render passes: UMoviePipelineDeferredPassBase (final color, world normal, base color, depth)
427
+ // Add passes to the PrimaryConfig to capture multiple AOVs per frame
428
+
429
+ UMoviePipelineQueue* Queue = NewObject<UMoviePipelineQueue>(this);
430
+ UMoviePipelineExecutorJob* Job =
431
+ Queue->AllocateNewJob(UMoviePipelineExecutorJob::StaticClass());
432
+
433
+ Job->Sequence = FSoftObjectPath(MySequence);
434
+ Job->Map = FSoftObjectPath(GetWorld());
435
+ Job->JobName = TEXT("MyRender");
436
+ Job->SetConfiguration(NewObject<UMoviePipelinePrimaryConfig>(Job));
437
+ // Add pass/output settings to Job->GetConfiguration() as needed.
438
+
439
+ // Execute the render (editor only — MovieRenderPipelineEditor module)
440
+ UMoviePipelineQueueEngineSubsystem* QueueSubsystem =
441
+ GEngine->GetEngineSubsystem<UMoviePipelineQueueEngineSubsystem>();
442
+ QueueSubsystem->RenderQueueWithExecutor(UMoviePipelineInProcessExecutor::StaticClass());
443
+ // For runtime/non-editor rendering, implement UMoviePipelineExecutorBase instead.
444
+ ```
445
+
446
+ ---
447
+
448
+ ## Common Mistakes
449
+
450
+ **Binding after Play**: Overrides applied after `Play()` miss frame 0.
451
+ Always `SetBinding*` before `Play()`.
452
+
453
+ **Multiplayer camera cuts**: Camera cuts only affect the local client.
454
+ Use `SeqActor->SetReplicatePlayback(true)` for server-driven sync.
455
+
456
+ **Camera not returning after cutscene**: Sequencer does not auto-restore the player camera.
457
+ Subscribe to `OnFinished` and call `SetViewTargetWithBlend` + re-enable input.
458
+
459
+ **GC of spawned sequence actor**: `CreateLevelSequencePlayer` returns a raw pointer.
460
+ Store `OutActor` in a `UPROPERTY()` member to prevent garbage collection.
461
+
462
+ **Skipping mid-sequence**: Call `SetCompletionModeOverride(ForceRestoreState)` before `Stop()`
463
+ so actors return to their pre-sequence state.
464
+
465
+ **PIE timing**: Avoid wall-clock assumptions; use `GetCurrentTime()` frame numbers.
466
+
467
+ **Deprecated direct property**: `SeqActor->SequencePlayer` is deprecated since UE 5.4.
468
+ Use `SeqActor->GetSequencePlayer()`.
469
+
470
+ **Wrong player instance**: Calling `Play()` on a stale or mismatched `ULevelSequencePlayer`
471
+ pointer (e.g., from a different `ALevelSequenceActor` in the level) produces no visible effect
472
+ or animates the wrong actors. Always retrieve the player from the specific `ALevelSequenceActor`
473
+ that owns the sequence you intend to drive.
474
+
475
+ ---
476
+
477
+ ## Related Skills
478
+
479
+ - `/ue-actor-component-architecture` — actor spawning and component setup for bound actors
480
+ - `/ue-animation-system` — skeletal animation tracks, AnimMontage integration in Sequencer
481
+ - `/ue-cpp-foundations` — delegate patterns, `UFUNCTION`, `UPROPERTY`
482
+ - `/ue-gameplay-framework` — PlayerController camera restoration, GameMode flow
483
+
484
+ ## Reference Files
485
+
486
+ - `references/sequencer-patterns.md` — common Sequencer setups: bindings, camera cuts, gameplay handoff
487
+
488
+ ---
489
+
490
+ ## Checklist
491
+
492
+ Validate before considering the work done:
493
+
494
+ - [ ] Gameplay state is restored correctly when the sequence ends or is skipped
495
+ - [ ] Sequences are bound through spawnables or resolvable bindings, not fragile references
496
+ - [ ] Render settings are separated from in-game playback settings
497
+ - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
498
+ - [ ] The Common Mistakes section of this skill was reviewed against the change
499
+
500
+ **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
501
+
502
+ ## Next Steps
503
+
504
+ - `/ue-world-level-streaming` — ensure required levels are loaded for the shot
505
+ - `/code-review` — architectural and quality review of the change
506
+ - `/commit` — conventional commit once the change is verified