2-2. Enhanced Input System을 활용한 입력 매핑 구현하기
1. PlayerController 이해하기
PlayerController
사용자가 키보드, 마우스, 게임패드 등에서 입력을 받으면, 그 입력을 해석하여 캐릭터나 다른 오브젝트에게 동작을 명령하는 핵심 클래스
언리얼 엔진의 중요한 철학 중 하나 "플레이어 입력은 PlayerController 에서 처리한다"
입력 처리 로직과 실제 캐릭터의 동작 로직을 분리 가능 → 코드를 구조적으로 관리하기가 훨씬 수월해짐
입력이 처리되는 기본 흐름
- 입력 장치로부터 사용자 조작 신호가 들어옴
- 이 신호는 PlayerController가 받아서 해석
- PlayerController가 현재 소유 (Possess)하고 있는 Pawn에게 이동, 회전, 공격 등의 구체적인 명령 지시
멀티플레이 환경
각 플레이어마다 개별 PlayerController가 생성 → 여러 사용자의 입력을 충돌 없이 분리하고 관리할 수 있음
PlayerController의 주요 기능
입력 처리
Enhanced Input 시스템 사용 → 액션/축 매핑을 보다 체계적으로 설정 가능
카메라 제어 로직
축 입력을 받아 캐릭터의 시점 회전이나 줌 인/아웃 같은 카메라 동작을 수행
HUD 및 UI와의 상호작용
언리얼의 UMG (언리얼 모션 그래픽) 기반 UI를 통해 버튼 클릭, 드래그, 터치 등의 이벤트
Possess / UnPossess
특정 Pawn에 빙의 (Possess)하여 해당 Pawn을 제어
UnPossess() 함수를 호출하여 Pawn과의 연결을 해제한 뒤, 다른 Pawn으로 바꿔 탈 수도 있음
2. PlayerController C++ 클래스 생성하기
C++ 클래스 APlayerController 생성
Tools → New C++ Class → Common Classes 목록 → Player Controller 선택 or 검색 창에 PlayerController를 입력 후 선택
Class Name : SpartaPlayerController
Class Type : Public
SpartaPlayerController.h

SpartaPlayerController.cpp

PlayerController를 GameMode에 적용
SpartaPlayerController 실제 사용을 위해 GameMode에 등록해야 함
SpartaGameMode.h

SpartaGameMode.cpp

PlayerControllerClass
- GameMode가 제공하는 속성
- 게임 시작 시 사용할 PlayerController 타입을 지정
PlayerController Blueprint 생성
블루프린트로 래핑(wrap)하는 과정
Content Browser → SpartaPlayerController 클래스를 우클릭 → Blueprint Class 선택
이름 설정: BP_SpartaPlayerController
BP_SpartaGameMode → Player Controller Class → BP_SpartaPlayerController 설정

3. Enhanced Input System의 이해 및 Input Action 설정하기
Enhanced Input System
언리얼 엔진 5에서 Project Settings → Input 시스템을 대체 및 확장을 위해 Enhanced Input 시스템을 제공
Input Action (IA)
캐릭터의 이동, 점프, 발사, 줌 등과 같이 특정 동작을 추상화한 단위
Input Action (IA) 설정
Value Type
Bool
단순 On/Off 토글 입력에 사용
예시: 점프(스페이스바), 공격(마우스 왼쪽 버튼)
Axis1D (1차원 축 값)
단일 축 (-1~1 범위)의 입력에 사용
예시: 게임패드 트리거(가속 페달), 전진/후진(W/S)
Axis2D (2차원 축 값)
X, Y 두 축을 동시에 처리할 때 사용
예시: 캐릭터 이동(WASD), 마우스 이동(가로+세로)
Axis3D (3차원 축 값)
X, Y, Z 세 축을 동시에 처리
예시: 비행 시뮬레이션에서 3축 제어
IA_Move
Value Type: Axis2D
앞/뒤, 왼/오른쪽 두 방향을 동시에 처리 → Value Type: Axis2D
IA_Look
Value Type: Axis2D
가로 (X축, 좌/우), 세로 (Y축, 위/아래) 움직임을 동시에 포함
IA_Jump
Value Type: Bool
On/Off로 동작 / Spacebar 키가 눌렸는지 여부만 중요
IA_Sprint
Value Type: Bool
Shift 키 값으로 속도를 늘리거나 줄이고를 설정
4. Input Mapping Context 설정하기
Input Mapping Context (IMC)
여러 개의 IA들을 모아놓은 매핑 설정 파일
게임 진행 중 특정 상황에서 IMC를 활성 (Enable)하거나 비활성 (Disable)하여 입력을 제어 가능
Input Mapping Context (IMC) 매핑
IA_Move
Swizzle Input Axis Values
- 입력 축 (Axis)을 변환하거나 재구성하는 기능
- 언리얼 엔진의 입력 시스템에서는 입력 데이터를 X, Y, Z 축 중 하나로 매핑
- Swizzle은 이 입력 값이 올바른 축에 맞지 않을 경우, 특정 축으로 재배치 혹은 변환할 수 있게 도와줌
전진/후진
W 키를 누르면 입력 값이 X축에 맞춰 정렬 (X축의 +1 방향에 매핑 → 추가 변환 필요없음 )
S 키의 입력 값도 Swizzle을 통해 X축으로 정렬 (X축의 반대방향 → Negate 입력 값 뒤집기 X축 -1)

좌/우
A 키를 누르면 입력 값이 Y축에 맞춰 정렬 (Y축의 반대방향 → Negate 입력 값 뒤집기 Y축 -1)
D 키의 입력값도 Swizzle을 통해 Y축으로 정렬 (Y축의 +1 방향에 매핑 → 추가 변환 필요없음)

IA_Look
Axis2D로 지정한 X축, Y축 값을 게임 내 좌표계에 맞춰 회전에 반영
기본적인 마우스의 움직임
Y축 위로 움직임 = 양수
Y축 아래로 움직임 = 음수
카메라의 상하 회전 (Pitch)은 엔진의 좌표계
위 = 음수, 아래 = 양수 로 작동하는 경우가 많음 → Y축 값을 Negate Modifier를 통해 반전
- 위로 움직임 → 음수(-) (카메라 위로)
- 아래로 움직임 → 양수(+) (카메라 아래로)
X축 (좌우 회전, Yaw) 기본적인 엔진 좌표계와 마우스 움직임의 방향이 일치
- 오른쪽 이동 → 양수(+)
- 왼쪽 이동 → 음수(-)

IA_Jump
Spacebar 로 키 지정 / 눌렀을 때 On/Off 형태로 동작
별도의 트리거나 모디파이어가 필요x
IA_Sprint
Left Shift 로 키 지정 / 눌렀을 때 On/Off 형태로 동작
별도의 트리거나 모디파이어가 필요x
5. PlayerController에서 IMC 활성화하기
PlayerController 클래스 준비
// SpartaPlayerController.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "SpartaPlayerController.generated.h"
class UInputMappingContext; // IMC 관련 전방 선언
class UInputAction; // IA 관련 전방 선언
UCLASS()
class SPARTAPROJECT_API ASpartaPlayerController : public APlayerController
{
GENERATED_BODY()
public:
ASpartaPlayerController();
// 에디터에서 세팅할 IMC
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputMappingContext* InputMappingContext;
// IA_Move를 지정할 변수
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputAction* MoveAction;
// IA_Look를 지정할 변수
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputAction* LookAction;
// IA_Jump를 지정할 변수
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputAction* JumpAction;
// IA_Sprint를 지정할 변수
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* SprintAction;
};
// SpartaPlayerController.cpp
#include "SpartaPlayerController.h"
ASpartaPlayerController::ASpartaPlayerController()
: InputMappingContext(nullptr),
MoveAction(nullptr),
JumpAction(nullptr),
LookAction(nullptr),
SprintAction(nullptr)
{
}
nullptr 로 초기화하는 이유
- 블루프린트 상에서 할당을 해줄 것이기 때문에 초기화
- 블루프린트에서 값을 할당하지 않은 상태로 게임을 시작하더라도 해당 변수는 안전한 nullptr 값을 가짐
IMC 활성화 코드 작성
// SpartaPlayerController.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "SpartaPlayerController.generated.h"
class UInputMappingContext; // IMC 관련 전방 선언
class UInputAction; // IA 관련 전방 선언
UCLASS()
class SPARTAPROJECT_API ASpartaPlayerController : public APlayerController
{
GENERATED_BODY()
public:
ASpartaPlayerController();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputMappingContext* InputMappingContext;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputAction* MoveAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputAction* LookAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Input")
UInputAction* JumpAction;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* SprintAction;
protected:
// BeginPlay로 IMC를 바로 활성화
virtual void BeginPlay() override;
};
// SpartaPlayerController.cpp
#include "SpartaPlayerController.h"
// Enhanced Input System의 Local Player Subsystem을 사용하기 위해 포함
#include "EnhancedInputSubsystems.h"
ASpartaPlayerController::ASpartaPlayerController()
: InputMappingContext(nullptr),
MoveAction(nullptr),
JumpAction(nullptr),
LookAction(nullptr),
SprintAction(nullptr)
{
}
void ASpartaPlayerController::BeginPlay()
{
Super::BeginPlay();
// 현재 PlayerController에 연결된 Local Player 객체를 가져옴
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
// Local Player에서 EnhancedInputLocalPlayerSubsystem을 획득
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
{
if (InputMappingContext)
{
// Subsystem을 통해 우리가 할당한 IMC를 활성화
// 우선순위(Priority)는 0이 가장 높은 우선순위
Subsystem->AddMappingContext(InputMappingContext, 0);
}
}
}
}
GetLocalPlayer()
- 현재 PlayerController가 관리하는 Local Player를 반환
GetSubsystem<UEnhancedInputLocalPlayerSubsystem>()
- 해당 Local Player에 부착된 Enhanced Input Subsystem을 반환
- 이를 통해 AddMappingContext나 RemoveMappingContext 등을 호출하여 입력 매핑을 동적으로 제어할 수 있음
SpartaInputMappingContext
활성화할 IMC
0: 우선순위. 숫자가 낮을수록 높은 우선순위를 가짐
BP_SpartaPlayerController → Details 패널을 확인

BP_SpartaPlayerController → 이벤트 그래프
enhanced action events 검색

문자열이 출력 테스트

게임을 플레이 후 → WASD, Spacebar, 마우스 이동 → 이벤트 노드가 정상적으로 호출되고 문자열 출력

'C++와 Unreal Engine으로 3D 게임 개발' 카테고리의 다른 글
| C++와 Unreal Engine으로 3D 게임 개발 2-4 (0) | 2026.06.12 |
|---|---|
| C++와 Unreal Engine으로 3D 게임 개발 2-3 (0) | 2026.06.10 |
| C++와 Unreal Engine으로 3D 게임 개발 2-1 (0) | 2026.06.10 |
| C++와 Unreal Engine으로 3D 게임 개발 1-7 (0) | 2026.06.08 |
| C++와 Unreal Engine으로 3D 게임 개발 1-6 (0) | 2026.06.08 |