
입력(Input)이 가장 하위 레벨에서 상위 레벨로 어떻게 흐르는지에 대한 전체적인 개요입니다. 아래는 각 사용자의 입력이 Unreal Engine에서 라우팅되는 순서대로 정리한 단계별 흐름입니다(각 단계는 다음 단계로 입력을 전달합니다):
FEngineLoop: Unreal Engine의 하트비트 틱으로, 플랫폼 SDK에 매 프레임마다 틱/업데이트를 알립니다.GenericApplication & FGenericApplicationMessageHandler: Windows/Mac/Xbox/Playstation 등 각 플랫폼의 SDK로, 엔진 초기화 시 Slate Application을 생성하고, 매 프레임마다 사용자별 입력을 전달합니다.FSlateApplication: 입력을 Input Processor, Slate UI, 게임 엔진(게임 코드)으로 라우팅합니다.IInputProcessor: Slate Application 내에 동적으로 추가/제거할 수 있는 C++ 객체로, 모든 입력을 가장 먼저 받아 처리하며, 입력을 소비할지 계속 라우팅할지 결정합니다.SWidget: 화면에 포커스된 UI 요소로, 입력을 받아 소비할 수 있습니다. UWidget도 여기서 입력을 받습니다(UMG 위젯은 Slate 위젯을 감싸는 UObject 기반 래퍼입니다).UGameViewportClient: Slate Application에서 Slate 요소로 전달된 입력이 소비되지 않으면, 뷰포트 위젯(게임의 최종 렌더 이미지를 나타내는 Slate 위젯)으로 전달되고, 여기서 Game Viewport Client로 라우팅됩니다.APlayerController: Game Viewport가 입력을 받으면, 게임 코드에서 사용할 수 있는지 확인한 뒤, Player Controller의 Input Stack에 추가합니다(ProcessPlayerInput에서 처리, Player Controller의 Tick에서 호출됨).UPlayerInput: Player Controller가 보유한 객체로, 입력을 Pawn 및 Input Stack에 있는 다른 객체로 라우팅합니다.UInputComponent: 게임 코드에서 입력을 받는 가장 일반적인 방법으로, 모든 액터에 존재하며 Player Controller의 Input Stack과 연결되어 엔진을 통해 입력을 전달받아 게임 코드에서 사용할 수 있습니다.
입력 흐름 다이어그램
Input Component는 모든 액터(AActor)에 존재하는 UActorComponent입니다.
이 컴포넌트는 프로젝트의 Axis Mapping과 Action Mapping에 바인딩되어 기능을 실행할 수 있습니다.
각 바인딩은 입력 이벤트를 소비(Consume)할 수 있으며, 한 Input Component가 입력 이벤트를 소비하면 입력 스택의 다른 컴포넌트에서는 해당 이벤트를 처리할 수 없습니다.
Input Component를 사용하면 액터가 입력 이벤트를 델리게이트 함수에 바인딩하여 자동으로 처리할 수 있습니다.
이러한 입력 처리는 두 개의 클래스에 의해 관리됩니다:
APlayerController:: 입력 스택을 구성하고, 입력 처리 순서와 우선순위를 제어합니다.UPlayerInput:: 델리게이트 함수 브로드캐스트 및 바인딩 사용 여부 판단을 담당합니다.아래는 실제로 매 프레임마다 입력 컴포넌트가 처리되는 순서입니다. 아래 다이어그램 참고
- [
APlayerController::TickPlayerInput]
- [
UPlayerInput::Tick]- 마우스 오버 이벤트 수집
- 터치 오버 이벤트 수집
- [
APlayerController::ProcessPlayerInput]
- [
APlayerController::BuildInputStack]: 입력 컴포넌트 스택을 빌드하고 처리 순서를 결정합니다. 오버라이드하여 순서 제어 가능.- [
UPlayerInput::ProcessInputStack]: 실제 입력 처리 시작.
- [
APlayerController::PreProcessInput]- 논-축(key) 상태 복사
- 입력 컴포넌트 스택을 위에서 아래로 하나씩 순회(각 루프마다 하나의 입력 컴포넌트 처리)
- 이 입력 컴포넌트의 키맵을 빌드하여 어떤 액션/축이 어떤 키 바인딩과 연결되는지 파악
- 터치 바인딩을 찾아 입력 액션 바인딩이 발생했는지 판단, 발생했다면 추적
- 제스처 바인딩을 찾아 입력 액션 바인딩이 발생했는지 판단, 발생했다면 추적
- 축 바인딩을 찾아 입력 축 바인딩이 발생했는지 판단, 발생했다면 추적
- 키를 소비할지 여부 결정(키맵 빌드와 이 단계 사이의 기록을 바탕으로)
- 각 입력 컴포넌트의 축 바인딩 값을 0으로 리셋
- 입력 액션을 해당 입력 컴포넌트에 브로드캐스트
- 입력 축을 해당 입력 컴포넌트에 브로드캐스트
- [
APlayerController::PostProcessInput]- [
UPlayerInput::FinishProcessingPlayerInput]: 이번 프레임의 입력 처리를 마무리하며, 입력이 유지되는지 저장하고 다음 프레임을 위해 값 정리- 브로드캐스트된 모든 바인딩 초기화
- 다음 프레임을 위해 입력 스택 리셋
- [
APlayerController::ProcessForceFeedbackAndHaptics]
레벨에서 입력이 틱(Tick)되고 처리되는 순서(즉, APlayerController의 TickPlayerInput에서 시작하는 입력 처리 순서)
입력 컴포넌트는 우선순위 스택을 가지며, 우선순위가 높은 액터가 먼저 입력을 소비할 수 있습니다. \
입력 컴포넌트의 우선순위 스택은 다음과 같습니다(높은 우선순위가 먼저 처리됨):
입력 컴포넌트의 우선순위 스택은 다음과 같습니다(높은 우선순위가 먼저 처리됨):

입력 컴포넌트 스택, Epic 공식 문서 참고
입력이 발생할 때마다 각 입력 유형에 대해 FInputEvent를 상속하는 구조체가 사용됩니다:
FModiferKeysState: 이 이벤트가 발생한 프레임의 수정 키(Shift, Ctrl 등) 상태.bool: 입력이 자동 반복(길게 눌러 반복 발생)된 것인지 여부.uint32: 이 이벤트를 발생시킨 Slate User의 인덱스.const FWidgetPath*: 이 이벤트와 함께 전달되는 이벤트 경로.모든 입력 이벤트 타입은 FInputEvent에서 파생됩니다:
FInputEvent: 키보드/게임패드의 키가 눌림/해제될 때의 이벤트. 해당 키 입력을 처리하는 이벤트 핸들러에 전달됩니다.FKey: 눌린 키의 이름.uint32: Unreal에서 사용하는 문자 코드(해당 키가 문자일 경우). 해당되지 않으면 0 반환.uint32: 하드웨어/SDK에서 받은 원본 문자 코드.FKeyEvent: 아날로그 입력(예: 스틱 축 값)을 나타냅니다.float: 0~1 값으로, 0은 미입력, 1은 최대 입력.FInputEvent: 키보드에서 UTF-16 코드(16비트 유니코드)가 입력될 때의 이벤트. OnKeyChar 기능에 사용.TCHAR: 입력된 문자.FInputEvent: 마우스/터치 입력(터치도 마우스 입력으로 간주, 항상 좌클릭으로 처리). Press/Release/Move 등 다양한 정보를 포함합니다.FVector2D: 현재 포인터의 화면 좌표.FVector2D: 이전 프레임의 포인터 화면 좌표.FVector2D: 현재와 이전 위치의 차이.const TSet<FKey>*: 현재 눌려 있는 마우스 버튼 집합.FKey: 이 이벤트가 나타내는 마우스 버튼(터치는 항상 좌클릭).uint32: 이 Slate User의 포인터(손가락) 인덱스.uint32: 터치패드 사용 시 포인터 인덱스.float: 터치/포인터 입력에 가해진 힘.bool: 터치(트랙패드 포함) 기반 이벤트인지 여부.EGestureType: 스와이프, 스크롤, 확대, 회전, 롱프레스 등 제스처 타입.FVector2D: 이전 제스처 이벤트 이후의 변화량.bool: 제스처 방향이 디바이스 기준으로 반전되었는지 여부.bool: 터치 힘 변화 이벤트인지 여부.bool: 첫 이동 터치 이벤트인지 여부.FInputEvent: 내부 자이로스코프를 사용하는 터치패드 이벤트(기울임, 회전 등).FVector: 디바이스/컨트롤러의 현재 기울기.FVector: 디바이스/컨트롤러의 회전 속도.FVector: 실제 중력 방향(지면 방향).FVector: 디바이스/컨트롤러의 3D 가속도.FInputEvent: 포커스 내비게이션(좌/우/상/하) 이벤트로, User Focus에 사용됩니다.EUINavigation: 내비게이션 방향(상/하/좌/우 등).ENavigationGenesis: 이 내비게이션 이벤트의 발생 원인(키보드/컨트롤러/사용자 등).WidgetBlueprintLibrary에는 Player Controller의 Input Mode를 설정하는 3가지 함수가 있습니다.
이 세 가지 상태는 입력 흐름의 6단계(Game Viewport Client)에서 실제로 어떤 일이 일어나는지 설명합니다.
실제로는 별도의 Input Mode가 존재하는 것이 아니라, Player Controller를 통해 Game Viewport Client의 값을 간편하게 변경하는 단축 기능입니다.
Input Mode 값에 대한 변경은 레벨/맵 이동 시에도 유지됩니다.
이는 Unreal Engine의 기본 기능을 사용하든, Game Viewport Client에서 직접 수동으로 값을 변경하든 동일하게 적용됩니다.
마우스 락 모드(EMouseLockMode)는 마우스 커서가 뷰포트(화면) 경계를 벗어나지 못하도록 잠그는 방식을 지정합니다. 각 모드는 다음과 같이 동작합니다:




참고: 마우스 락 모드는 각 뷰포트(플레이어별 분할 화면 포함) 단위로 적용됩니다. "Window" 모드는 모든 뷰포트를 포함한 전체 창(Window) 기준으로 동작합니다.