게임 개발/학습 일지

언리얼 C++ - Enhanced_input_System을 활용한 입력 매핑 구현하기

이개 2026. 4. 16. 12:59

입력을 받는 Player Controller

플레이어 컨트롤러는 입력을 받아서 Player Class에서 전달만 하고, 결과는 Player Class에서 처리한다.

 

플레이어 컨트롤러의 역할

  • 입력 처리 - Enhanced Input System
  • 카메라 제어 로직
  • UI와의 상호작용
    • 드래그 앤 드롭 또는 버튼 누르기 등
  • Possess/ UnPossess

 

플레이어 컨트롤러 만들기

PlayerController를 만든다.

GameMode 헤더 클래스에서 PlayerControllerClass를 선언한다.

 

이제 블루프린트로 래핑을 한번 해준다.

그 후, GameMode에서 Player Controller 클래스를 BP_만들었던 컨트롤러 클래스로 변경한다.

게임모드에서 바꾸면 프로젝트 세팅에서도 자동으로 연동되어 적용된다.

 

이상태로 게임 실행을 하면 플레이어 컨트롤러가 아웃라이너에 정상 출력되는 것을 볼 수 있다.

 

Enhanced Input System

원래 인풋 시스템이 있었는데, 향상된 인풋 시스템이 새로 나오면서 대체되었다.

  • Input Mapping System(IMC)
    • IA를 관리하는 시스템
  • Input Action(IA)
    • 어떤 동작을 추상화한 것.
      • 점프 -> IA_Jump
      • 마우스 회전-> IA_Look
      • 이동 -> IA_Move

 

캐릭터 행동

  1. 이동 WASD
  2. 마우스 회전
  3. 점프
  4. 스프린트

 

콘텐츠 드로어 우클릭 -> Input에서 IA_Move라는 파일을 만든다.

  • Value Type
    • 입력 동작이 발생했을 때, 어떤 유형의 값을 변환시킬 것인가를 결정
      • Digital(bool)은 단순 입력 여부 판단
      • Axis1D(float)는 단일 축(자동차 등에서 사용)
      • Axis2D(Vector2D)는 X, Y 두 축을 동시에 처리
      • Axis3D(Vector)는 X, Y, Z 세 축을 동시에 처리(비행 시뮬레이터 등에 사용)
  • Triggers
    • 동작이 수행되는 조건. 일반적인 Move 입력 정도는 따로 지정해줄 필요가 없다.
      • Pressed: 누를 때
      • Released: 키를 뗄 때
      • Hold: 오랜 시간 누르고 있을 때
      • Combo: 여러 번 누를 때
  • Modifiers
    • DeadZone: 미세한 입력을 조정.
    • Negate: 입력 값 반전
    • Scalar: 입력값 크기 배율 확대
    • Swizzle Input Axis Values: 입력값에 축을 재구성해준다.

Swizzle Input Axis Values로 다양한 축을 지정할 수 있다.

 

 

IA_Move는 Value Type에  Axis2D(Vector2D) 정도만 지정하고 나머지는 비워둔다.

 

IA_Jump도 만들어준다.

 

Jump 또한 트리거나 모디파이어가 있을 필요 없다.
IA_Sprint도 똑같이 만든다.

 

IA_Look는 Value Type을 Axis2D로 설정한다.

 

 

IMC_Character라는 이름의 Input Mapping Context를 만든다.

 

 

IA_Move부터 추가한다.
키보드 아이콘을 누르고 원하는 키를 누르면 해당 키가 선택된다.
Swizzle Input Axis Values를 넣고 XZY로 축을 바꿔준다.

전진이 X축을 기준으로 1을 움직히는 것이기 때문에 X를 앞으로 해줘야한다. 이전 블루프린트 수업 때는 Swizzel Input Axis Values를 따로 정해주지 않았는데, 이번 강의에서는 전부 따로 설정해준다.

 

앞뒤 이동은 XZY, 좌우이동은 YXZ 축으로 설정해준다.

 

Jump는 스페이바 할당만 해주면 된다.
IA_Look는 Mouse XY 2D-Axis로 설정한다.

 

Modifier는 Negate로 하고, Y축에만 체크되어 반대로 적용되게 한다. Z축은 쓰지 않고, X축은 그대로 사용해도 무방하기 때문이다.

 

 

IA_Sprint는 왼쪽 Shift키로 할당하고 저장한다.

 

 

PlayerController.h를 수정한다.

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "SpartaPlayerController.generated.h"

class UInputMappingContext;
class UInputAction;

/**
 * 
 */
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* JumpAction;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "input")
	UInputAction* LookAction;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "input")
	UInputAction* SprintAction;
	
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "SpartaPlayerController.h"
#include "EnhancedInputSubsystems.h"

ASpartaPlayerController::ASpartaPlayerController(): 
	InputMappingContext(nullptr), // 아무것도 할당하지 않는 것보다는 nullptr을 할당해주는 것이 좋다.
	MoveAction(nullptr),
	JumpAction(nullptr),
	LookAction(nullptr),
	SprintAction(nullptr)
{

}

void ASpartaPlayerController::BeginPlay()
{
	Super::BeginPlay();

	// 플레이어를 가져오기 -> 향상된 입력 관리하는 서브시스템 획득하기 -> IMC 객체 확인하고 서브시스템에 IMC 추가하며 우선순위를 최우선으로 두고 활성화시키기
	if (ULocalPlayer* LocalPlayer = GetLocalPlayer()) // GetLocalPlayer는 플레이어의 로컬 객체를 가져옴
	{
		if (UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>()) // 입력 시스템을 관리하는 서브시스템. IMC를 추가하거나 삭제하는 역할을 한다.
		{
			if (InputMappingContext) // 인풋 매핑 컨텍스트가 존재하면
			{
				Subsystem->AddMappingContext(InputMappingContext, 0); // InputMappingContext로 활성화함. 0은 우선순위를 뜻함.
			}
		}
	}
}

 

 

Player Controller 블루프린트에 들어가서 Input을 하나하나 할당해준다.

UPROPERTY로 등록해놓은 항목들. 설정에 맞게 매핑해준다.

 

Event로 생성해준다.

 

매핑 확인을 위해 String 출력을 해본다.

Play하여 잘 나오는지 확인한다.

정상 출력되는 것을 확인할 수 있다.