본문 바로가기

[C++과 Unreal Engine으로 3D 게임 개발] 입력 매핑 구현

@iamrain2025. 9. 19. 11:57

PlayerController

PlayerController는 키보드, 마우스, 게임패드 등에서 받은 입력을 캐릭터나 오브젝트에게 해석해서 전달하는 클래스다.

언리얼 엔진의 중요한 철학 중 하나는 "플레이어 입력은 PlayerController에서 처리한다"는 것이다.

입력이 처리되는 기본 흐름

  1. 입력 장치로부터 사용자 조작 신호
  2. PlayerController가 신호를 해석
  3. 현재 소유(Possess)하고 있는 Pawn에게 구체적인 명령

PlayerController의 주요 기능

입력처리

  • 다양한 입력 장치의 이벤트를 처리
  • 언리얼 엔진 5에서 제공하는 Enhanced Input 시스템을 사용하면 액션 / 축 매핑을 체계적으로 설정할 수 있음.

카메라 제어 로직

  • 축 입력을 받아 캐릭터의 시점 회전이나 줌 인 / 아웃 같은 카메라 동작을 수행

HUD 및 UI와의 상호작용

  • 언리얼의 UMG(언리얼 모션 그래픽) 기반 UI를 통해 이벤트를 PlayerController에서 받을 수 있음

Possess / UnPossess

  • 특정 Pawn에 "빙의(Possess)"하여 해당 Pawn을 제어
  • 필요할 때 `UnPossess()` 함수를 호출해 Pawn과 연결을 해제한 뒤, 다른 Pawn으로 변경 가능

 

PlayerController C++ 클래스

PlayerController를 GameMode 적용

#include "SpartaGameMode.h"
#include "SpartaCharacter.h"
#include "SpartaPlayerController.h"

ASpartaGameMode::ASpartaGameMode()
{
	DefaultPawnClass = ASpartaCharacter::StaticClass();

	PlayerControllerClass = ASpartaPlayerController::StaticClass();
}

 

저장 후 빌드 → 언리얼 에디터에서 기본 PlayerController가 적용된 것을 확인 가능

PlayerController 동작 확인

게임 실행 후 Outliner에 인스턴스가 표시 된 것을 확인

 

Enhanced Input System의 이해 및 Input Action 설정

Enhanced Input System이란?

언리얼 엔진 5에서 이전 버전에 사용하던 전역 `Project Settings → Input` 시스템을 대체하거나 확장하기 위해 제공하는 시스템.

Input Action (IA)

캐릭터의 이동, 점프, 발사, 줌과 같이 특정 동작을 추상화한 단위를 IA라고 한다.

 

Input Mapping Context (IMC)

IMC는 여러 개의 IA를 한데 모아놓은 매핑 설정 파일

 

PlayerController에서 IMC 활성화

#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;
};

 

#include "SpartaPlayerController.h"

ASpartaPlayerController::ASpartaPlayerController()
	: InputMappingContext(nullptr),
	MoveAction(nullptr),
	JumpAction(nullptr),
	LookAction(nullptr),
	SprintAction(nullptr)
{
}

IMC 활성화 코드 작성

언리얼 5의 Enhanced Input System은 `Local Player Subsystem`을 통해 활성화하거나 비활성화한다.

 

Local Player Subsystem

  • 게임이 실행되면 각 플레이어를 표현하기 위해 Local Player 객체를 생성
  • UEnhancedInputLocalPlayerSubsystem은 Local Player에 부착되어, 사용할 입력 매핑(IMC)을 관리
#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;

	virtual void BeginPlay() override;
};
#include "SpartaPlayerController.h"
#include "EnhancedInputSubsystems.h"

ASpartaPlayerController::ASpartaPlayerController()
	: InputMappingContext(nullptr),
	MoveAction(nullptr),
	JumpAction(nullptr),
	LookAction(nullptr),
	SprintAction(nullptr)
{
}

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

	if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
	{
		if (UEnhancedInputLocalPlayerSubsystem* Subsystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
		{
			if (InputMappingContext)
			{
				Subsystem->AddMappingContext(InputMappingContext, 0);
			}
		}
	}
}

IMC 적용 확인 및 테스트

iamrain
@iamrain :: Annals of Unreal

iamrain 님의 블로그 입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차