Sequencer 아키텍처
UE5 시퀀서의 핵심 구조와 데이터 흐름을 이해하고, 런타임 평가 시스템의 동작 원리를 학습합니다
시퀀서란 무엇인가
UE5 시네마틱 도구의 핵심 엔진
Sequencer는 Unreal Engine의 비선형 시네마틱 편집 도구입니다. 영화 제작의 타임라인 기반 편집 워크플로를 게임 엔진 내에서 구현하며, 카메라 워크, 캐릭터 애니메이션, VFX, 오디오 등 모든 시네마틱 요소를 하나의 타임라인에서 제어합니다.
시퀀서의 핵심 역할
- 인게임 시네마틱 - 컷씬, 대화 시퀀스, 인트로/아웃트로
- 게임플레이 연출 - 스크립트 이벤트, 카메라 전환, 환경 변화
- 영상 제작 - 트레일러, 프리비즈, 최종 렌더링
- 실시간 방송 - 버추얼 프로덕션, 라이브 이벤트
UE4의 Matinee가 완전히 폐기되고 Sequencer가 유일한 시네마틱 도구가 되었습니다. UE 5.4+부터는 Movie Render Graph가 추가되어 렌더링 파이프라인이 대폭 강화되었습니다.
핵심 클래스 구조
시퀀서를 구성하는 C++ 클래스 계층
ULevelSequence
시퀀서 에셋의 최상위 컨테이너입니다. Content Browser에 .uasset으로 저장되며,
내부에 UMovieScene 객체를 보유합니다.
// ULevelSequence는 UMovieSceneSequence를 상속
class ULevelSequence : public UMovieSceneSequence
{
// 핵심 멤버: 시네마틱 데이터를 담는 UMovieScene
UMovieScene* MovieScene;
// 오브젝트 바인딩 - 시퀀서와 월드 액터 연결
FMovieSceneObjectBindingID BindingID;
// 시퀀스에 포함된 서브시퀀스 참조
TArray<UMovieSceneSequence*> SubSequences;
};
UMovieScene
실제 타임라인 데이터를 관리하는 핵심 클래스입니다. 트랙(Track), 섹션(Section), 오브젝트 바인딩(Object Binding)을 포함합니다.
| 클래스 | 역할 | 모듈 |
|---|---|---|
| ULevelSequence | 시퀀스 에셋 컨테이너 | LevelSequence |
| UMovieScene | 타임라인 데이터 관리 | MovieScene |
| UMovieSceneTrack | 트랙 베이스 클래스 | MovieScene |
| UMovieSceneSection | 섹션(시간 범위 + 데이터) | MovieScene |
| FMovieSceneChannel | 키프레임 채널 | MovieScene |
| ALevelSequenceActor | 월드에 배치되는 시퀀스 액터 | LevelSequence |
| ULevelSequencePlayer | 런타임 재생 컨트롤러 | LevelSequence |
C++에서 시퀀서를 사용하려면 PublicDependencyModuleNames에 "MovieScene", "LevelSequence"를 추가해야 합니다.
Object Binding 시스템
시퀀서와 월드 오브젝트를 연결하는 메커니즘
Object Binding은 시퀀서 에셋 내의 트랙과 실제 월드에 존재하는 Actor/Component를 연결하는 시스템입니다. 이 추상화 덕분에 하나의 시퀀스를 여러 레벨에서 다른 액터에 바인딩하여 재사용할 수 있습니다.
Possessable vs Spawnable
Possessable (빙의형)
레벨에 이미 존재하는 액터를 참조합니다. 시퀀서가 해당 액터를 "빙의"하여 제어합니다.
- 레벨에 배치된 액터 필요
- 시퀀스 종료 후 액터 유지
- 런타임 바인딩 변경 가능
Spawnable (스폰형)
시퀀서가 직접 액터를 스폰하고 관리합니다. 시퀀스 종료 시 자동 제거됩니다.
- 레벨에 사전 배치 불필요
- 시퀀스가 라이프사이클 관리
- 독립적이고 이식 가능
// Possessable 바인딩 생성
FGuid BindingGuid = MovieScene->AddPossessable(
ActorLabel, // 표시 이름
Actor->GetClass() // 바인딩 대상 클래스
);
// Spawnable로 변환
FGuid SpawnableGuid = MovieScene->MakeSpawnable(BindingGuid);
// 런타임에서 바인딩 오버라이드
FMovieSceneObjectBindingID BindingID;
BindingID.SetGuid(BindingGuid);
LevelSequenceActor->SetBinding(BindingID, {TargetActor});
Possessable은 레벨 내 액터의 경로(Path)로 참조하기 때문에, 액터를 이동하거나 이름을 변경하면 바인딩이 깨질 수 있습니다. 프로덕션에서는 Spawnable을 선호하는 경우가 많습니다.
평가 시스템 (Evaluation)
시퀀서가 매 프레임 데이터를 처리하는 과정
UE 4.26부터 시퀀서의 내부 아키텍처가 데이터 지향 설계(Data-Oriented Design)로 전면 리팩토링되었습니다. 이 구조는 UE5에서도 동일하게 유지됩니다.
평가 4단계 파이프라인
| 단계 | 실행 시점 | 역할 |
|---|---|---|
| Spawn | 바운더리 변경 시 | Spawnable 액터 생성/파괴 |
| Instantiation | 바인딩 무효화 시 | 트랙/섹션 인스턴스화, 바인딩 재확인 |
| Evaluation | 매 프레임 | 키프레임 보간, 프로퍼티 값 계산 |
| Finalization | 매 프레임 | 계산된 값을 실제 오브젝트에 적용 |
// FMovieSceneEvaluationTemplate - 컴파일된 평가 데이터
// 시퀀서는 에디터에서 "컴파일"되어 최적화된 평가 템플릿을 생성
struct FMovieSceneEvaluationTemplate
{
// 시간 범위별 그룹화된 평가 트리
FMovieSceneEvaluationTree EvaluationTree;
// 실제 섹션별 평가 데이터
TMap<FMovieSceneTrackIdentifier,
FMovieSceneEvaluationTrack> Tracks;
};
// 런타임 평가 순서
// 1. EntityManager가 활성 엔터티 수집
// 2. 각 시스템이 엔터티를 병렬 처리
// 3. Linker가 최종 값을 오브젝트에 적용
Spawn과 Instantiation 단계는 경계(Boundary)가 변경될 때만 실행되므로 매 프레임 비용이 발생하지 않습니다. 실제 매 프레임 비용은 Evaluation과 Finalization에서만 발생합니다.
데이터 흐름 아키텍처
에셋에서 월드까지의 전체 데이터 경로
전체 아키텍처 다이어그램
(에셋)
(월드 배치)
(재생 엔진)
(트랙 + 섹션)
(컴파일된 데이터)
(최종 적용)
모듈 구성
| 모듈 | 유형 | 설명 |
|---|---|---|
| MovieScene | Runtime | 핵심 데이터 구조 (Track, Section, Channel) |
| MovieSceneTracks | Runtime | 빌트인 트랙 구현 (Transform, Float, Bool 등) |
| LevelSequence | Runtime | ULevelSequence, Player, Actor |
| Sequencer | Editor | 시퀀서 에디터 UI |
| MovieSceneTools | Editor | 트랙 에디터, 커브 에디터 |
MovieScene, MovieSceneTracks, LevelSequence는 런타임 모듈로 패키징된 게임에서도 사용 가능합니다.
Sequencer, MovieSceneTools는 에디터 전용이므로 런타임 코드에서 참조하면 안 됩니다.
핵심 요약
- ULevelSequence는 시퀀서 에셋의 최상위 컨테이너이며, 내부에 UMovieScene이 모든 트랙/섹션 데이터를 관리한다
- Object Binding은 Possessable(기존 액터 참조)과 Spawnable(시퀀서가 직접 스폰) 두 가지 방식이 있다
- 평가 시스템은 Spawn → Instantiation → Evaluation → Finalization 4단계 파이프라인으로 동작한다
- Spawn/Instantiation은 경계 변경 시에만 실행되어 매 프레임 성능 부담이 없다
- 런타임 모듈(MovieScene, LevelSequence)과 에디터 모듈(Sequencer)을 구분하여 의존성을 관리해야 한다
- ALevelSequenceActor가 월드에 배치되고, ULevelSequencePlayer가 실제 재생을 담당한다
도전 과제
배운 내용을 직접 실습해보세요
Content Browser에서 Level Sequence를 생성하고 레벨에 배치하세요. Actor를 시퀀서에 추가하여 Transform 트랙에 위치 키프레임을 설정하고, 시퀀스 재생을 확인하세요.
동일한 Actor를 Possessable과 Spawnable 두 방식으로 시퀀서에 추가하세요. 시퀀스 재생 시작/종료 시 Actor 라이프사이클 차이를 관찰하고 장단점을 정리하세요.
C++에서 ULevelSequencePlayer를 생성하고, Play/Pause/Stop/SetPlaybackPosition API로 시퀀스를 프로그래밍적으로 제어하는 시스템을 구현하세요.