$npx -y skills add quodsoler/unreal-engine-skills --skill ue-sequencer-cinematicsUse this skill when working with Sequencer, LevelSequence, cutscene, cinematic, camera, movie scene, sequencer event, or Movie Render Queue in Unreal Engine. See references/sequencer-patterns.md for dialogue cutscene, in-game camera, and scripted event patterns. For animation pla
| 1 | # Skill: ue-sequencer-cinematics |
| 2 | |
| 3 | You are an expert in Unreal Engine's Sequencer and cinematic systems. |
| 4 | |
| 5 | ## Context Check |
| 6 | |
| 7 | Read `.agents/ue-project-context.md` before writing any cinematic code for: |
| 8 | - Target UE version (API availability varies — SequencePlayer property deprecated in 5.4+) |
| 9 | - Cinematic requirements (cutscenes, in-game cameras, offline rendering) |
| 10 | - Multiplayer context (sequence replication behavior differs) |
| 11 | - Build.cs modules already declared |
| 12 | |
| 13 | ## Information Gathering |
| 14 | |
| 15 | Ask for: |
| 16 | 1. Cinematic type: full-screen cutscene, in-game camera, or background ambient sequence |
| 17 | 2. Whether actors bind at runtime or are pre-placed in the level |
| 18 | 3. Whether camera control must return to the player after playback |
| 19 | 4. One-shot or looping sequence |
| 20 | 5. Real-time gameplay or offline Movie Render Queue output |
| 21 | |
| 22 | --- |
| 23 | |
| 24 | ## Build.cs Modules |
| 25 | |
| 26 | ```csharp |
| 27 | PublicDependencyModuleNames.AddRange(new string[] |
| 28 | { |
| 29 | "LevelSequence", "MovieScene", "CinematicCamera", |
| 30 | }); |
| 31 | // Offline rendering only: |
| 32 | PrivateDependencyModuleNames.Add("MovieRenderPipelineCore"); |
| 33 | ``` |
| 34 | |
| 35 | --- |
| 36 | |
| 37 | ## Playing Level Sequences |
| 38 | |
| 39 | ### ALevelSequenceActor — World-Placed |
| 40 | |
| 41 | `ALevelSequenceActor` owns the player. Use `GetSequencePlayer()` — the direct `SequencePlayer` |
| 42 | property is deprecated since UE 5.4. |
| 43 | |
| 44 | ```cpp |
| 45 | // LevelSequenceActor.h: ULevelSequencePlayer* GetSequencePlayer() const; |
| 46 | ULevelSequencePlayer* Player = SeqActor->GetSequencePlayer(); |
| 47 | if (Player) { Player->Play(); } |
| 48 | ``` |
| 49 | |
| 50 | ### ULevelSequencePlayer::CreateLevelSequencePlayer — Runtime Spawn |
| 51 | |
| 52 | ```cpp |
| 53 | // LevelSequencePlayer.h: |
| 54 | // static ULevelSequencePlayer* CreateLevelSequencePlayer( |
| 55 | // UObject* WorldContextObject, ULevelSequence*, FMovieSceneSequencePlaybackSettings, |
| 56 | // ALevelSequenceActor*& OutActor); |
| 57 | |
| 58 | FMovieSceneSequencePlaybackSettings Settings; |
| 59 | Settings.bAutoPlay = false; |
| 60 | Settings.PlayRate = 1.0f; |
| 61 | Settings.LoopCount.Value = 0; // 0=once, -1=infinite |
| 62 | Settings.bDisableMovementInput = true; |
| 63 | Settings.bDisableLookAtInput = true; |
| 64 | Settings.bHidePlayer = false; |
| 65 | Settings.bHideHud = false; |
| 66 | Settings.bDisableCameraCuts = false; |
| 67 | Settings.bPauseAtEnd = false; |
| 68 | Settings.FinishCompletionStateOverride = |
| 69 | EMovieSceneCompletionModeOverride::ForceRestoreState; // safe for skippable cutscenes |
| 70 | |
| 71 | ALevelSequenceActor* OutActor = nullptr; |
| 72 | ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer( |
| 73 | this, Sequence, Settings, OutActor); |
| 74 | |
| 75 | // Store OutActor in a UPROPERTY to prevent GC |
| 76 | ActiveSequenceActor = OutActor; |
| 77 | |
| 78 | if (Player) |
| 79 | { |
| 80 | Player->OnFinished.AddDynamic(this, &AMyClass::OnCutsceneFinished); |
| 81 | Player->Play(); |
| 82 | } |
| 83 | ``` |
| 84 | |
| 85 | ### Play Control (UMovieSceneSequencePlayer base) |
| 86 | |
| 87 | ```cpp |
| 88 | // MovieSceneSequencePlayer.h |
| 89 | Player->Play(); |
| 90 | Player->PlayReverse(); |
| 91 | Player->PlayLooping(-1); // -1 = infinite loops |
| 92 | Player->Pause(); |
| 93 | Player->Stop(); // moves cursor to end, fires OnStop |
| 94 | Player->StopAtCurrentTime(); |
| 95 | Player->GoToEndAndStop(); |
| 96 | Player->SetPlayRate(0.5f); // negative = reverse |
| 97 | |
| 98 | // Jump to frame (skips events between current and target) |
| 99 | // Blueprint exposes this as GoToFrame. In C++, use SetPlaybackPosition with Jump. |
| 100 | Player->SetPlaybackPosition( |
| 101 | FMovieSceneSequencePlaybackParams(FFrameTime(120), EUpdatePositionMethod::Jump)); |
| 102 | |
| 103 | // Play through to frame (triggers all events along the way) |
| 104 | Player->PlayTo( |
| 105 | FMovieSceneSequencePlaybackParams(FFrameTime(240), EUpdatePositionMethod::Play), |
| 106 | FMovieSceneSequencePlayToParams()); |
| 107 | |
| 108 | // Restrict play range |
| 109 | Player->SetFrameRange(0, 60); // frames 0–60 |
| 110 | Player->SetTimeRange(0.0f, 2.5f); // seconds |
| 111 | |
| 112 | // State query |
| 113 | bool bPlaying = Player->IsPlaying(); |
| 114 | FQualifiedFrameTime Now = Player->GetCurrentTime(); |
| 115 | FQualifiedFrameTime Dur = Player->GetDuration(); |
| 116 | |
| 117 | // Delegates (bind before Play) |
| 118 | Player->OnFinished.AddDynamic(this, &UMyClass::OnSeqFinished); |
| 119 | Player->OnPlay.AddDynamic(this, &UMyClass::OnSeqPlay); |
| 120 | Player->OnStop.AddDynamic(this, &UMyClass::OnSeqStop); |
| 121 | Player->OnNativeFinished.BindUObject(this, &UMyClass::OnNativeFinished); // non-dynamic |
| 122 | |
| 123 | // Camera cut event (LevelSequencePlayer.h) |
| 124 | // DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnLevelSequencePlayerCameraCutEvent, UCameraComponent*, CameraComponent) |
| 125 | LsPlayer->OnCameraCut.AddDynamic(this, &UMyClass::OnCameraCut); |
| 126 | |
| 127 | // Restore state on early stop (skippable cutscene) |
| 128 | Player->SetCompletionModeOverride(EMovieSceneCompletionModeOverride::ForceRestoreState); |
| 129 | Player->Stop(); |
| 130 | |
| 131 | // Sub-sequence snapshot |
| 132 | FLevelSequencePlayerSnapshot Snap; |
| 133 | Player->TakeFrameSnapshot(Snap); |
| 134 | // Snap.CurrentShotName, Snap.RootTime, Snap.CameraComponent |