1. 향상된 입력 시스템
과거 언리얼 엔진에서는 Project Settings의 Engine - Input 탭에서 Axis Mapping과 Action Mapping을 통해 입력을 설정하고 이후 SetupPlayerInputComponent 함수를 통해 상호작용을 코딩하는 방식을 사용했다 듣고있는 강의에서는 5.0 버전인지 이 방식을 사용하고 있었지만 앞으로 5.6 혹은 5.7로 개발을 해야하기에 이 향상된 시스템을 따로 공부해서 적용 시키는 과정이 생각보다 오래걸렸다
2. 향상된 입력 시스템 핵심 개념
향상된 입력 시스템은 크게 Input Action, Input Mapping Context, Triggers, Modifiers 네 가지 핵심 요소로 구성된다.
2.1. IA(Input Action)
- 특정 사용자 입력에 이름을 붙여 프로그램 내에서 쉽게 참조하고 관리할 수 있게 해주는 Data Asset이다
- bool 값이나 1D Axis 혹은 2D Vector 등 다양한 Value Type을 가질 수 있으며 이 타입이 액션의 동작을 결정한다
- 점프 발사 달리기 같은 행동 자체를 정의하는 역할을 한다
2.2. IMC(Input Mapping Context)
- 하나 이상의 Input Action과 이에 대응하는 키보드나 마우스 버튼 매핑을 그룹화하는 규칙서이다
- 상황에 따라 특정 입력 매핑 세트를 동적으로 활성화하거나 비활성화할 수 있다
- Context에 Priority를 지정하여 같은 입력을 사용하려는 여러 액션 간의 충돌을 해결할 수 있다
2.3. Triggers
- 어떤 조건이 만족되었을 때 액션을 실행할 것인지 결정하는 규칙이다
- 키를 누르는 순간이나 누르고 있는 동안 혹은 뗄 때 등 실행 시점을 정의한다
2.4. Modifiers
- 하드웨어에서 들어온 Raw Input Data를 코드가 사용하기 좋게 변형하는 가공 단계이다
- 입력값의 축을 변경하거나 부호를 반전시키는 등의 사전 처리를 담당하여 코드를 단순화해준다
3. 탱크의 W A S D 이동을 위한 Modifiers 설정 원리
키보드 입력은 기본적으로 X축 신호로 들어온다. 2D Vector를 사용할 때 앞뒤 이동은 Y축이고 좌우 이동은 X축으로 처리하는 것이 일반적이다. 따라서 W와 S 키의 신호를 Y축으로 옮겨주는 작업이 반드시 필요하다.

| W | Swizzle Input Axis Values | 1.0 (X축) -> 1.0 (Y축) | (0.0 1.0) | 전진 |
| S | Swizzle Input Axis Values & Negate | 1.0 (X축) -> 1.0 (Y축) -> -1.0 (Y축) | (0.0 -1.0) | 후진 |
| D | 없음 | 변화 없음 | (1.0 0.0) | 우회전 |
| A | Negate | 1.0 (X축) -> -1.0 (X축) | (-1.0 0.0) | 좌회전 |
3.1. Swizzle Input Axis Values
- 입력받는 하드웨어의 Vector값을 다른 축으로 재배열하여 이사시키는 기능이다
- 방향이나 부호를 뒤집는 것이 아니라 데이터가 들어가는 방의 위치만 바꿔주는 것이다
- W를 누르면 X축으로 1.0이 들어오지만 이 Modifier를 거치면 Y축 값이 1.0이 되어 전진 신호로 사용할 수 있게 된다
3.2. Negate
- 들어온 숫자 값의 부호를 반전시키는 기능이다
- 1.0이 들어오면 -1.0으로 만들어 후진이나 좌회전처럼 방향을 반대로 바꿀 때 사용한다
4. C++ 환경 설정 및 헤더 파일 작성
향상된 입력을 C++ 코드에서 사용하려면 모듈을 추가하고 변수를 선언하는 과정이 필요하다.
4.1. Build.cs 파일 수정
향상된 입력은 플러그인 기반이므로 프로젝트가 이 모듈을 사용할 수 있도록 빌드 설정에 추가해야 한다
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" });
5. C++ 소스 파일 구현
기본 폰 클래스의 가상 함수들을 Override하여 엔진의 흐름에 탱크만의 입력 로직을 끼워 넣는다.
5.1. Mapping Context 활성화 (BeginPlay)
게임이 시작될 때 우리가 만든 입력 규칙서를 시스템에 적용하라고 명령하는 단계이다
플레이어 컨트롤러에서 Enhanced Input Local Player Subsystem을 가져와서 AddMappingContext 함수로 Priority와 함께 등록한다
void ATank::BeginPlay()
{
Super::BeginPlay();
if (APlayerController* PlayerController = Cast<APlayerController>(GetController()))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(TankMappingContext, 0);
}
}
}
5.2. 액션과 함수 Binding (SetupPlayerInputComponent)
플레이어가 폰에 Possess될 때 호출되며 입력 신호와 실행할 C++ 함수를 연결하는 배선 작업이다
CastChecked를 사용하여 일반 컴포넌트를 Enhanced Input Component로 강제 형변환하고 실패 시 게임을 종료하여 안전성을 확보한다
BindAction 함수를 통해 Action Asset과 Trigger Event 그리고 실행할 대상과 함수의 주소를 묶어준다
void ATank::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
{
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ATank::Move);
}
}
5.3. 입력 신호 추출 및 로직 실행 (Move)
엔진이 전달해준 데이터 주머니에서 2D Vector 값을 꺼내어 실제 움직임에 적용한다
에디터에서 Swizzle로 설정한 덕분에 Y축 값으로 전진과 후진을 완벽하게 구분할 수 있다
void ATank::Move(const FInputActionValue& Value)
{
FVector2D MovementVector = Value.Get<FVector2D>();
float ForwardValue = MovementVector.Y;
float RightValue = MovementVector.X;
if (ForwardValue != 0.f || RightValue != 0.f)
{
UE_LOG(LogTemp, Warning, TEXT("전진: %f 회전: %f"), ForwardValue, RightValue);
}
}
6. Live Coding 주의사항
자꾸 C++기반으로 만든 블루프린트 Pawn의 컴포넌트 구조나 Mesh가 계속 날라가서 C++클래스를 다시 빌드하는 일이 발생하길래 이유를 찾아봤더니 원인은 Live Coding에 있었다
6.1. 블루프린트 컴포넌트 유실 오류
에디터 실행 시 Failed to load Outer for resource 오류가 뜨는 것은 C++ 코드와 블루프린트 사이의 연결이 끊어졌을 때 발생했다
C++ 생성자에서 CreateDefaultSubobject 함수 안에 적어준 문자열 이름을 도중에 변경하면 블루프린트가 기존 부품을 찾지 못해 데이터가 꼬이게 된다
6.2. Live Coding과 Cold Build의 차이
Live Coding은 실행 중인 엔진 메모리에 코드를 덧칠하는 방식이라 함수 내부의 로직이나 수치를 간단하게 변경할 때만 사용하는 것이 좋다
변수를 추가하거나 삭제하고 헤더 파일의 구조를 바꾸거나 빌드 설정 파일을 수정하는 등 뼈대를 건드리는 작업은 메모리 구조 자체가 바뀌는 일이다
이러한 중요한 작업을 할 때는 반드시 에디터를 종료하고 비주얼 스튜디오에서 솔루션을 다시 빌드하는 Cold Build를 수행해야 에러를 예방할 수 있다
알 수 없는 오류 코드가 발생하며 빌드가 꼬였을 때는 프로젝트 폴더 내의 Binaries 및 Intermediate 폴더를 삭제하고 프로젝트 파일을 다시 생성하는 것이 가장 확실한 해결책이다
'언리얼엔진 > 언리얼엔진 공부노트' 카테고리의 다른 글
| 언리얼 공부노트 : 탱크 이동 및 포탑 회전 시스템 구현 (0) | 2026.04.04 |
|---|---|
| 언리얼 공부노트 : 트러플 슈팅 (0) | 2026.04.04 |
| 언리얼 공부노트: BasePawn 설계와 탱크 컴포넌트 구조 잡기 (0) | 2026.04.01 |
| 언리얼 공부 노트: 루멘, 포인터, 그리고 물리 상호작용의 핵심 (0) | 2026.03.25 |
| 언리얼 엔진 5 C++ 공부 과정 (2) | 2026.03.16 |