Communitygithub.com

ComeOnOliver/skillshub

You are an expert in Unreal Engine's Sequencer and cinematic systems.

skillshub란 무엇인가요?

skillshub is a Cursor agent skill that you are an expert in Unreal Engine's Sequencer and cinematic systems.

지원 대상~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/ComeOnOliver/skillshub/tree/HEAD/skills/quodsoler/unreal-engine-skills/ue-sequencer-cinematics

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Skill: ue-sequencer-cinematics

You are an expert in Unreal Engine's Sequencer and cinematic systems.

Context Check

Read .agents/ue-project-context.md before writing any cinematic code for:

  • Target UE version (API availability varies — SequencePlayer property deprecated in 5.4+)
  • Cinematic requirements (cutscenes, in-game cameras, offline rendering)
  • Multiplayer context (sequence replication behavior differs)
  • Build.cs modules already declared

Information Gathering

Ask for:

  1. Cinematic type: full-screen cutscene, in-game camera, or background ambient sequence
  2. Whether actors bind at runtime or are pre-placed in the level
  3. Whether camera control must return to the player after playback
  4. One-shot or looping sequence
  5. Real-time gameplay or offline Movie Render Queue output

Build.cs Modules

PublicDependencyModuleNames.AddRange(new string[]
{
    "LevelSequence", "MovieScene", "CinematicCamera",
});
// Offline rendering only:
PrivateDependencyModuleNames.Add("MovieRenderPipelineCore");

Playing Level Sequences

ALevelSequenceActor — World-Placed

ALevelSequenceActor owns the player. Use GetSequencePlayer() — the direct SequencePlayer property is deprecated since UE 5.4.

// LevelSequenceActor.h: ULevelSequencePlayer* GetSequencePlayer() const;
ULevelSequencePlayer* Player = SeqActor->GetSequencePlayer();
if (Player) { Player->Play(); }

ULevelSequencePlayer::CreateLevelSequencePlayer — Runtime Spawn

// LevelSequencePlayer.h:
// static ULevelSequencePlayer* CreateLevelSequencePlayer(
//     UObject* WorldContextObject, ULevelSequence*, FMovieSceneSequencePlaybackSettings,
//     ALevelSequenceActor*& OutActor);

FMovieSceneSequencePlaybackSettings Settings;
Settings.bAutoPlay              = false;
Settings.PlayRate               = 1.0f;
Settings.LoopCount.Value        = 0;       // 0=once, -1=infinite
Settings.bDisableMovementInput  = true;
Settings.bDisableLookAtInput    = true;
Settings.bHidePlayer            = false;
Settings.bHideHud               = false;
Settings.bDisableCameraCuts     = false;
Settings.bPauseAtEnd            = false;
Settings.FinishCompletionStateOverride =
    EMovieSceneCompletionModeOverride::ForceRestoreState; // safe for skippable cutscenes

ALevelSequenceActor* OutActor = nullptr;
ULevelSequencePlayer* Player  = ULevelSequencePlayer::CreateLevelSequencePlayer(
    this, Sequence, Settings, OutActor);

// Store OutActor in a UPROPERTY to prevent GC
ActiveSequenceActor = OutActor;

if (Player)
{
    Player->OnFinished.AddDynamic(this, &AMyClass::OnCutsceneFinished);
    Player->Play();
}

Play Control (UMovieSceneSequencePlayer base)

// MovieSceneSequencePlayer.h
Player->Play();
Player->PlayReverse();
Player->PlayLooping(-1);       // -1 = infinite loops
Player->Pause();
Player->Stop();                // moves cursor to end, fires OnStop
Player->StopAtCurrentTime();
Player->GoToEndAndStop();
Player->SetPlayRate(0.5f);     // negative = reverse

// Jump to frame (skips events between current and target)
// Blueprint exposes this as GoToFrame. In C++, use SetPlaybackPosition with Jump.
Player->SetPlaybackPosition(
    FMovieSceneSequencePlaybackParams(FFrameTime(120), EUpdatePositionMethod::Jump));

// Play through to frame (triggers all events along the way)
Player->PlayTo(
    FMovieSceneSequencePlaybackParams(FFrameTime(240), EUpdatePositionMethod::Play),
    FMovieSceneSequencePlayToParams());

// Restrict play range
Player->SetFrameRange(0, 60);           // frames 0–60
Player->SetTimeRange(0.0f, 2.5f);       // seconds

// State query
bool bPlaying = Player->IsPlaying();
FQualifiedFrameTime Now = Player->GetCurrentTime();
FQualifiedFrameTime Dur = Player->GetDuration();

// Delegates (bind before Play)
Player->OnFinished.AddDynamic(this, &UMyClass::OnSeqFinished);
Player->OnPlay.AddDynamic(this, &UMyClass::OnSeqPlay);
Player->OnStop.AddDynamic(this, &UMyClass::OnSeqStop);
Player->OnNativeFinished.BindUObject(this, &UMyClass::OnNativeFinished); // non-dynamic

// Camera cut event (LevelSequencePlayer.h)
// DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnLevelSequencePlayerCameraCutEvent, UCameraComponent*, CameraComponent)
LsPlayer->OnCameraCut.AddDynamic(this, &UMyClass::OnCameraCut);

// Restore state on early stop (skippable cutscene)
Player->SetCompletionModeOverride(EMovieSceneCompletionModeOverride::ForceRestoreState);
Player->Stop();

// Sub-sequence snapshot
FLevelSequencePlayerSnapshot Snap;
Player->TakeFrameSnapshot(Snap);
// Snap.CurrentShotName, Snap.RootTime, Snap.CameraComponent, Snap.ActiveShot

Actor Binding

Tag bindings in Sequencer (right-click object binding -> Tags...) then override at runtime. Always bind before calling Play().

Spawnables vs Possessables

Possessables bind to pre-existing world actors (placed in level or spawned by gameplay). Spawnables are actors the sequence itself creates and destroys.

// Spawnable: sequence owns the actor lifecycle
// Set in Sequencer editor: right-click actor track → "Change to Spawnable"
// At runtime, actor spawns when sequence reaches its range, despawns when exiting

// Dynamic possessable: bind a gameplay-spawned actor to a sequence track
// Create the binding ID in the editor, then override at runtime:
FMovieSceneObjectBindingID BindingID = /* from sequence editor */;
ALevelSequenceActor* SeqActor = /* your sequence actor */;
SeqActor->SetBinding(BindingID, {SpawnedActor});

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.

// LevelSequenceActor.h — all binding API lives here

// Replace bound actors (preferred: tag-based, resilient to GUID changes)
SeqActor->SetBindingByTag(FName("Hero"), TArray<AActor*>{ HeroActor },
    /*bAllowBindingsFromAsset=*/ false);

// GUID-based (expose FMovieSceneObjectBindingID via UPROPERTY for editor assignment)
// UPROPERTY(EditAnywhere) FMovieSceneObjectBindingID HeroBindingID;
SeqActor->SetBinding(HeroBindingID, TArray<AActor*>{ HeroActor }, false);

// Append without removing existing bindings
SeqActor->AddBindingByTag(FName("NPC"), NpcActor, /*bAllowBindingsFromAsset=*/ true);

// Remove / reset
SeqActor->RemoveBindingByTag(FName("NPC"), NpcActor);
SeqActor->ResetBinding(HeroBindingID);  // revert to asset binding
SeqActor->ResetBindings();              // revert all overrides

// Lookup by tag
FMovieSceneObjectBindingID ID = SeqActor->FindNamedBinding(FName("Hero"));
const TArray<FMovieSceneObjectBindingID>& All = SeqActor->FindNamedBindings(FName("NPC"));

// Inspect what is currently bound
TArray<UObject*> Bound = Player->GetBoundObjects(HeroBindingID);

// FMovieSceneObjectBindingID (MovieSceneObjectBindingID.h):
//   Access via public accessors — internal fields are private:
//     GetGuid()              — FGuid identifying the binding track
//     GetRelativeSequenceID() — which sub-sequence holds it (0 = local)

Camera System

ACineCameraActor / UCineCameraComponent

// CineCameraActor.h: UCineCameraComponent* GetCineCameraComponent() const;
// CineCameraComponent.h / CineCameraSettings.h:
//   FCameraFilmbackSettings Filmback  (SensorWidth, SensorHeight in mm, read-only SensorAspectRatio)
//   FCameraLensSettings LensSettings  (MinFocalLength, MaxFocalLength, MinFStop, MaxFStop mm)
//   FCameraFocusSettings FocusSettings (FocusMethod, ManualFocusDistance cm, bSmoothFocusChanges)
//   float CurrentFocalLength  — Interp, animatable in Sequencer
//   float CurrentAperture     — f-stop, Interp-animatable

ACineCameraActor* Cam = GetWorld()->SpawnActor<ACineCameraActor>(SpawnTransform);
UCineCameraComponent* CC = Cam->GetCineCameraComponent();

FCameraFilmbackSettings FB;
FB.SensorWidth = 36.0f; FB.SensorHeight = 24.0f;  // full-frame 35mm
CC->SetFilmback(FB);

CC->SetCurrentFocalLength(50.0f);   // mm
CC->SetCurrentAperture(2.0f);       // f-stop

FCameraFocusSettings FS;
FS.FocusMethod         = ECameraFocusMethod::Manual;  // Manual | Tracking | Disable | DoNotOverride
FS.ManualFocusDistance = 500.0f;    // cm
FS.bSmoothFocusChanges = true;
CC->SetFocusSettings(FS);

// Lookat tracking (CineCameraActor.h: FCameraLookatTrackingSettings LookatTrackingSettings)
Cam->LookatTrackingSettings.bEnableLookAtTracking     = true;
Cam->LookatTrackingSettings.ActorToTrack              = TargetActor;
Cam->LookatTrackingSettings.LookAtTrackingInterpSpeed = 5.0f;
Cam->LookatTrackingSettings.RelativeOffset            = FVector(0, 0, 90.f);

// Prevent sequence from overriding gameplay camera (set before Play)
SeqActor->PlaybackSettings.bDisableCameraCuts = true;

// Restore player camera after cutscene (call from OnFinished delegate)
APlayerController* PC = GetWorld()->GetFirstPlayerController();
PC->SetViewTargetWithBlend(PC->GetPawn(), 0.5f, VTBlend_Cubic);
PC->SetIgnoreMoveInput(false);
PC->SetIgnoreLookInput(false);

APlayerCameraManager

APlayerCameraManager (accessed via PlayerController->PlayerCameraManager) manages camera blending and view target selection for the local player. After a cutscene ends, restore the gameplay camera explicitly — Sequencer does not do this automatically:

APlayerController* PC = GetWorld()->GetFirstPlayerController();
// PlayerCameraManager handles blend state; SetViewTargetWithBlend triggers it.
PC->SetViewTargetWithBlend(PC->GetPawn(), 0.5f, VTBlend_Cubic);
// The blend is processed each tick inside APlayerCameraManager::UpdateCamera.

Sequencer Events

Event tracks call UFUNCTIONs on objects in the event context. Default event context: UWorld + ALevelScriptActor.

// Function must be UFUNCTION(BlueprintCallable) on a context object
UFUNCTION(BlueprintCallable, Category = "Cinematics")
void TriggerExplosion()
{
    ExplosionSystem->SpawnExplosion(ExplosionLocation);
}

// Trigger C++ code at a specific frame by playing to it (fires all events in range)
Player->PlayTo(
    FMovieSceneSequencePlaybackParams(FFrameTime(60), EUpdatePositionMethod::Play),
    FMovieSceneSequencePlayToParams());

FMovieSceneEvent

FMovieSceneEvent holds the event endpoint data — the bound function to call when the event fires. Event tracks are structured as:

  • UMovieSceneEventTrack — the master track added to a binding or as a master track
  • UMovieSceneEventTriggerSection — a section containing one or more trigger entries
  • FMovieSceneEvent — each entry inside the trigger section, pointing to the endpoint function

The endpoint function is resolved at runtime against the event context objects (by default UWorld and ALevelScriptActor). Director-based events resolve against a ULevelSequenceDirector subclass instance.

ULevelSequenceDirector — Custom Event Context

ULevelSequenceDirector provides a per-sequence scripting context that receives event track calls. Subclass it (Blueprint or C++) and assign to the LevelSequence asset's Director Class property. The Director instance is created when the sequence begins playing and destroyed when it stops — its lifetime matches the sequence player.

// MySequenceDirector.h
#include "LevelSequenceDirector.h"
#include "MySequenceDirector.generated.h"

UCLASS(Blueprintable)
class UMySequenceDirector : public ULevelSequenceDirector
{
    GENERATED_BODY()
public:
    // Called from Sequencer event tracks — bind to event key in the Sequencer editor
    UFUNCTION(BlueprintCallable, Category = "Cinematics")
    void OnDialogueStart(FName SpeakerTag);

    UFUNCTION(BlueprintCallable, Category = "Cinematics")
    void OnCutsceneChoice(int32 ChoiceIndex);
};

// MySequenceDirector.cpp
void UMySequenceDirector::OnDialogueStart(FName SpeakerTag)
{
    // Access the sequence player and bound actors from within the Director.
    // ULevelSequenceDirector.h: UPROPERTY ULevelSequencePlayer* Player (direct field, no getter)
    TArray<UObject*> Bound = Player->GetBoundObjects(SpeakerBindingID);
    // Trigger gameplay logic: UI, dialogue system, camera focus, etc.
}

Why Director over Level Script: The Director travels with the sequence asset, not the level. Reusable across maps. Supports per-sequence state (member variables). Level Script events only work when the sequence is placed in that specific level.


MovieScene Tracks

// MovieScene.h — get from the LevelSequence asset
UMovieScene* MS = SeqActor->GetSequence()->GetMovieScene();

// Possessables (world actors) — iterate by index
for (int32 i = 0; i < MS->GetPossessableCount(); ++i)
{
    const FMovieScenePossessable& P = MS->GetPossessable(i);
}
// Spawnables (sequence-owned actors) — iterate by index
for (int32 i = 0; i < MS->GetSpawnableCount(); ++i)
{
    const FMovieSceneSpawnable& S = MS->GetSpawnable(i);
}

// Master tracks (not bound to any actor)
const TArray<UMovieSceneTrack*>& Masters = MS->GetTracks();

// Tracks on a specific binding
const FMovieSceneBinding* B = MS->FindBinding(SomeGuid);
if (B) { for (UMovieSceneTrack* T : B->GetTracks()) { /* cast to subtype */ } }
Track ClassPurpose
UMovieScene3DTransformTrackTransform animation
UMovieSceneSkeletalAnimationTrackSkeletal mesh animation
UMovieSceneEventTrackEvent triggers
UMovieSceneAudioTrackAudio
UMovieSceneFadeTrackScreen fade
UMovieSceneCameraCutTrackCamera cuts
UMovieSceneSubTrackSub-sequences
UMovieScenePropertyTrackArbitrary UPROPERTY animation (base class)

All track types require MovieSceneTracks in Build.cs.

Custom tracks: subclass UMovieSceneTrack + UMovieSceneSection for domain-specific animation data. Register via ISequencerModule::RegisterTrackEditor. This is an advanced pattern — most needs are met by UMovieScenePropertyTrack subclasses.

UMovieScenePropertyTrack animates arbitrary UPROPERTY values on bound objects. Common concrete subclasses: UMovieSceneFloatTrack (float properties), UMovieSceneBoolTrack (bool properties), UMovieSceneColorTrack (FLinearColor / FColor properties). Each creates sections of the matching type (e.g., UMovieSceneFloatSection) that store a FMovieSceneFloatChannel.

Sub-Sequences

// Add a sub-sequence track to a master UMovieScene
UMovieScene* MasterMS = MasterSequence->GetMovieScene();
UMovieSceneSubTrack* SubTrack = MasterMS->AddTrack<UMovieSceneSubTrack>();

// Add a child sequence — AddSequence(Sequence, StartFrame, Duration)
FFrameRate DisplayRate = MasterMS->GetDisplayRate();
FFrameNumber Start = (2.0 * DisplayRate).FloorToFrame(); // 2 seconds in
int32 Duration = (5.0 * DisplayRate).FloorToFrame().Value; // 5 seconds long
UMovieSceneSubSection* SubSection =
    SubTrack->AddSequence(ChildLevelSequence, Start, Duration);

// Configure sub-section timing
SubSection->Parameters.TimeScale = 1.0;   // FMovieSceneTimeWarpVariant (double), playback speed multiplier
SubSection->Parameters.bCanLoop = false;

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.

Time Dilation and SlowMo

For SlowMo effects during sequences, use Player->SetPlayRate(0.5f) on the sequence player — this is independent of UGameplayStatics::SetGlobalTimeDilation and does not affect world physics or other gameplay systems. Combine with a post-process motion blur intensity increase for cinematic slow motion without disrupting gameplay state.


Movie Render Queue

// MovieRenderPipelineCore module. Classes:
//   UMoviePipelineQueue           — holds jobs
//   UMoviePipelineExecutorJob     — sequence + map + config per job
//   UMoviePipelinePrimaryConfig   — root settings container
//   UMoviePipelineOutputSetting   — output path, file name format, frame rate
// Output formats: UMoviePipelineImageSequenceOutput_PNG / _EXR, UMoviePipelineAppleProResOutput
// Render passes: UMoviePipelineDeferredPassBase (final color, world normal, base color, depth)
//   Add passes to the PrimaryConfig to capture multiple AOVs per frame

UMoviePipelineQueue* Queue = NewObject<UMoviePipelineQueue>(this);
UMoviePipelineExecutorJob* Job =
    Queue->AllocateNewJob(UMoviePipelineExecutorJob::StaticClass());

Job->Sequence = FSoftObjectPath(MySequence);
Job->Map      = FSoftObjectPath(GetWorld());
Job->JobName  = TEXT("MyRender");
Job->SetConfiguration(NewObject<UMoviePipelinePrimaryConfig>(Job));
// Add pass/output settings to Job->GetConfiguration() as needed.

// Execute the render (editor only — MovieRenderPipelineEditor module)
UMoviePipelineQueueEngineSubsystem* QueueSubsystem =
    GEngine->GetEngineSubsystem<UMoviePipelineQueueEngineSubsystem>();
QueueSubsystem->RenderQueueWithExecutor(UMoviePipelineInProcessExecutor::StaticClass());
// For runtime/non-editor rendering, implement UMoviePipelineExecutorBase instead.

Common Mistakes

Binding after Play: Overrides applied after Play() miss frame 0. Always SetBinding* before Play().

Multiplayer camera cuts: Camera cuts only affect the local client. Use SeqActor->SetReplicatePlayback(true) for server-driven sync.

Camera not returning after cutscene: Sequencer does not auto-restore the player camera. Subscribe to OnFinished and call SetViewTargetWithBlend + re-enable input.

GC of spawned sequence actor: CreateLevelSequencePlayer returns a raw pointer. Store OutActor in a UPROPERTY() member to prevent garbage collection.

Skipping mid-sequence: Call SetCompletionModeOverride(ForceRestoreState) before Stop() so actors return to their pre-sequence state.

PIE timing: Avoid wall-clock assumptions; use GetCurrentTime() frame numbers.

Deprecated direct property: SeqActor->SequencePlayer is deprecated since UE 5.4. Use SeqActor->GetSequencePlayer().

Wrong player instance: Calling Play() on a stale or mismatched ULevelSequencePlayer pointer (e.g., from a different ALevelSequenceActor in the level) produces no visible effect or animates the wrong actors. Always retrieve the player from the specific ALevelSequenceActor that owns the sequence you intend to drive.


Related Skills

  • ue-actor-component-architecture — actor spawning and component setup for bound actors
  • ue-animation-system — skeletal animation tracks, AnimMontage integration in Sequencer
  • ue-cpp-foundations — delegate patterns, UFUNCTION, UPROPERTY
  • ue-gameplay-framework — PlayerController camera restoration, GameMode flow

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

ComeOnOliver/skillshub

Create stunning, animation-rich HTML presentations from scratch or by converting PowerPoint files. Use when the user wants to build a presentation, convert a PPT/PPTX to web, or create slides for a talk/pitch. Helps non-designers discover their aesthetic through visual exploration rather than abstract choices.

ComeOnOliver/skillshub

Next.js 16+ 和 Turbopack — 增量打包、文件系统缓存、开发速度,以及何时使用 Turbopack 与 webpack。

ComeOnOliver/skillshub

SwiftUI architecture patterns, state management with @Observable, view composition, navigation, performance optimization, and modern iOS/macOS UI best practices.

ComeOnOliver/skillshub

See, Understand, Act on video and audio. See- ingest from local files, URLs, RTSP/live feeds, or live record desktop; return realtime context and playable stream links. Understand- extract frames, build visual/semantic/temporal indexes, and search moments with timestamps and auto-clips. Act- transcode and normalize (codec, fps, resolution, aspect ratio), perform timeline edits (subtitles, text/image overlays, branding, audio overlays, dubbing, translation), generate media assets (image, audio, video), and create real time alerts for events from live streams or desktop capture.

ComeOnOliver/skillshub

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

ComeOnOliver/skillshub

Next.js 15 애플리케이션을 위한 프론트엔드 개발 가이드라인. React 19, TypeScript, Shadcn/ui, Tailwind CSS를 사용한 모던 패턴. Server Components, Client Components, App Router, 파일 구조, Shadcn/ui 컴포넌트, 성능 최적화, TypeScript 모범 사례 포함. 컴포넌트, 페이지, 기능 생성, 데이터 페칭, 스타일링, 라우팅, 프론트엔드 코드 작업 시 사용.

ComeOnOliver/skillshub

Provides Tamagui patterns for config v4, compiler optimization, styled context, and cross-platform styling. Must use when working with Tamagui projects (tamagui.config.ts, @tamagui imports).

ComeOnOliver/skillshub

Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.

ComeOnOliver/skillshub

Create high-converting, visually distinctive landing pages. Use when building marketing pages, product launches, SaaS homepages, or any single-page conversion-focused website. Guides section-by-section composition with anti-AI-slop principles.

ComeOnOliver/skillshub

Auto-loaded context for Portfolio Buddy 2 development. Use for ANY task involving: React 19 development, TypeScript, portfolio analysis features, metrics calculations, trading strategy comparison, or working with the Portfolio Buddy 2 codebase. Contains tech stack, known issues, and architectural constraints.

ComeOnOliver/skillshub

Next.js development tooling via MCP. Inspect routes, components, build info, and debug Next.js apps. Use when working on Next.js applications, debugging routing, or inspecting app structure. NOT for general React or non-Next.js projects.

ComeOnOliver/skillshub

Implement UI using Shadcn MCP (atoms/theme) and 21st.dev MCP (complex sections). Use when adding buttons, layouts, or generating landing pages.

ComeOnOliver/skillshub

A conceptual skill for building an API client in Next.js that handles JWT tokens

ComeOnOliver/skillshub

Best practices and patterns for Next.js App Router, Server Actions, and Routing in this project.

ComeOnOliver/skillshub

The Design System, Theme, and UX rules for the Physical AI Hub.

ComeOnOliver/skillshub

Comprehensive frontend development skill for building modern, performant web applications using ReactJS, NextJS, TypeScript, Tailwind CSS. Includes component scaffolding, performance optimization, bundle analysis, and UI best practices. Use when developing frontend features, optimizing performance, implementing UI/UX designs, managing state, or reviewing frontend code.

ComeOnOliver/skillshub

This document captures learnings from fixing keyboard navigation issues when floating components (Select, DropdownMenu, Popover) have CSS open/close animations.

ComeOnOliver/skillshub

Build Next.js 16 applications with correct patterns and distinctive design. Use when creating pages, layouts, dynamic routes, upgrading from Next.js 15, or implementing proxy.ts. Covers breaking changes (async params/searchParams, Turbopack, cacheComponents) and frontend aesthetics. NOT when building non-React or backend-only applications.

ComeOnOliver/skillshub

Comprehensive Framer Motion animation library for React. Covers motion components, variants, gestures, page transitions, and scroll animations. Use when adding animations to React/Next.js applications.

ComeOnOliver/skillshub

Build interfaces that resonate, not just render. This skill enforces bold, intentional

관련 스킬