플레이어 컨트롤러
입력장치(키보드, 마우스, 게임패드 등)에서 입력을 하면 플레이어 컨트롤러에서 입력을 받고 플레이어 컨트롤러가 소유하고 있는 폰에게 명령을 내린다.
주요 기능
1. 다양한 입력장치의 이벤트를 처리한다.
2. 마우스나 게임패드의 축 입력을 받아 카메라 동작을 수행할 수 있다.
3. 언리얼의 UMG 기반 UI를 통해 버튼 클릭, 드래그, 터치 등의 이벤트를 컨트롤러에서 받을 수 있다.
(인벤토리 열기, 스킬 사용 등의 명령을 UI에서 트리거하면 컨트롤러가 해석해 폰, 게임모드 등 다른 시스템으로 전달 가능)
4. 특정 폰에 빙의해서 폰을 제어하고 필요할 때 Unpossess로 연결을 해제하고 다른 폰과 연결이 가능하다.
5. 멀티플레이 시 각 플레이어마다 고유한 컨트롤러가 있어 서로 다른 캐릭터 조작이 가능하다.
클래스 생성
플레이어 컨트롤러 C++파일을 생성한 후 게임모드의 컨트롤러로 지정한다.
#include "FirstGameMode.h"
#include "JinCharacter.h"
#include "JinPlayerController.h"
AFirstGameMode::AFirstGameMode()
{
DefaultPawnClass = AJinCharacter::StaticClass();
PlayerControllerClass = AJinPlayerController::StaticClass();
}
PlayerControllerClass는 GameMode가 제공하는 속성으로, 게임 시작 시 사용할 PlayerController 타입을 지정합니다.
AJinPlayerController::StaticClass()는 언리얼 엔진이 AJinPlayerController클래스의 정보를 런타임에 참조할 수 있도록 제공하는 정적 함수입니다.
위 코드를 저장 후 프로젝트 빌드를 완료하면, 언리얼 에디터에서 GameMode가 SpartaPlayerController를 기본 PlayerController로 인식하게 됩니다.
C++로 만든 컨트롤러 클래스를 손쉽게 편집할 수 있도록 블루프린트로 래핑하는 과정을 거친다.(C++ -> 블루프린트로 만들기)
게임모드의 Player Controller Class를 만든 BP_컨트롤러로 바꾼다.
게임을 실행해서 아웃라이너에 생성이 잘 되는지 확인한다.
인핸스드 인풋 시스템
입력 설정을 “입력 맵(Input Mapping Context, IMC)”과 “입력 액션(Input Action, IA)”이라는 개념으로 나누어 관리한다.
IA와 IMC는 C++가 아닌 언리얼엔진 에디터에서 생성한다.
인풋 액션(IA)
IA는 캐릭터의 이동, 점프, 발사, 줌 등과 같이 특정 동작을 추상화한 단위이다.
이동은 IA_Move, 점프는 IA_Jump, 마우스 회전(시점)은 IA_Look 등으로 만들 수 있다.
Value Type
IA가 입력 동작을 발생시킬 때 어떤 유형의 값을 제공할지 결정하는 옵션이다.
- Bool (참/거짓)
- 단순 On/Off 토글 입력에 사용됩니다.
- 예) 점프(스페이스바), 공격(마우스 왼쪽 버튼)
- Axis1D (1차원 축 값)
- 단일 축 (-1~1 범위)의 입력에 사용됩니다.
- 예) 게임패드 트리거(가속 페달), 전진/후진(W/S)
- Axis2D (2차원 축 값)
- X, Y 두 축을 동시에 처리할 때 사용됩니다.
- 예) 캐릭터 이동(WASD), 마우스 이동(가로+세로)
- Axis3D (3차원 축 값)
- X, Y, Z 세 축을 동시에 처리합니다.
- 예) 비행 시뮬레이션에서 3축 제어
트리거
입력이 활성화되는 특정 조건을 말한다.
- Pressed Trigger: 키를 누르는 순간에만 작동.
- Hold Trigger: 키를 일정 시간 눌렀을 때 작동.
- Released Trigger: 키를 뗄 때 작동.
모디파이어
입력 값을 수정하거나 변환하기 위한 설정이다.
- Scale : 입력 값에 일정 배율을 곱해줌 (마우스 이동 속도 2배)
- Invert : 입력 값을 반전 (상하 반전 카메라)
- Deadzone : 일정 임계값보다 작은 입력은 무시 (게임패드 조이스틱 미세 떨림 방지)
인풋 매핑 컨텍스트(IMC)
IMC는 여러 개의 IA를 모아놓은 매핑 설정 파일이다.
예를 들어 플레이어 기본 이동, 점프, 시점 전환 을 하나의 IMC에 넣고 UI 전용 입력을 다른 IMC로 분리하는 식으로 관리할 수 있다.
게임 진행 중 특정 상황에서 IMC를 활성화, 비화성화 하여 입력을 제어할 수 있다.
IMC에서 생성한 IA들을 어떤 키로 입력 받을건지 알맞게 매핑한다.
플레이어 컨트롤러에서 IMC 활성화 하기
플레이어 컨트롤러 헤더에 IA와 IMC를 C++ 멤버 변수로 선언하고 에디터에서 지정할 수 있도록 리플렉션 처리를 한다.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputMappingContext* InputMappingContext;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* Move;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* Jump;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* Look;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
UInputAction* Sprint;
생성자 멤버 초기화 리스트로 변수를 nullptr로 초기화한다.
AJinPlayerController::AJinPlayerController()
: InputMappingContext(nullptr),
Move(nullptr),
Jump(nullptr),
Look(nullptr),
Sprint(nullptr)
{
}
이렇게 선언해두면 에디터나 블루프린트에서 해당 멤버 변수에 만든 IA와 IMC를 할당할 수 있다.
이제 C++에서 실제로 IMC를 활성화 하는 코드를 작성한다.
언리얼 5의 인핸스드 인풋 시스템은 Local Player System을 통해 IMC를 활성화하거나 비활성화한다.
Local Player System
게임이 실행될 때 언리얼은 각 플레이어를 표현하기 위해 Local Player 객체를 생성한다.
싱글플레이어 상황에서는 하나의 로컬 플레이어, 로컬 멀티플레이(한 화면에서 여러 명 플레이)라면 플레이어 수 만큼 로컬 플레이어가 생성된다.
UEnhancedInputLocalPlayerSubsystem은 로컬 플레이어에 부착되어 해당 플레이어가 사용할 IMC를 관리한다.
이를 통해 플레이 중에 동적으로 다른 IMC를 추가, 제거하여 입력 모드를 전환할 수 있다.
예시) 전투중(IMC_Character) -> UI창 열림(IMC_UI) -> 전투 종료 후 다시(IMC_Character)
플레이어 컨트롤러.cpp에서 블루프린트에서 지정해둔 IMC를 활성화 하는 코드를 추가한다.
void AJinPlayerController::BeginPlay()
{
Super::BeginPlay();
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
{
if (InputMappingContext)
{
Subsystem->AddMappingContext(InputMappingContext, 0);
}
}
}
}
- GetLocalPlayer()
- 현재 PlayerController가 관리하는 Local Player를 반환합니다.
- GetSubsystem<UEnhancedInputLocalPlayerSubsystem>()
- 해당 Local Player에 부착된 Enhanced Input Subsystem을 반환합니다.
- 이를 통해 AddMappingContext나 RemoveMappingContext 등을 호출하여 입력 매핑을 동적으로 제어할 수 있습니다.
- AddMappingContext()
- 주어진 IMC를 Subsystem에 추가하여 입력 매핑을 활성화합니다.
- SpartaInputMappingContext: 활성화할 IMC.
- 0: 우선순위. 낮을수록 높은 우선순위를 가집니다.
- 이 함수를 여러 번 호출해 여러 IMC를 활성화할 수도 있습니다.
- 우선순위를 달리 부여해, 특정 IMC가 다른 IMC보다 우선순위가 높도록 설정할 수도 있습니다.
아직 이 부분은 이해가 잘 되지 않지만 공부를 더 한 후에 다시 볼 예정이다.
적용한 IMC가 잘 연결됐는지 확인해본다.
플레이어 컨트롤러 블루프린트의 이벤트 그래프에서 만들어 둔 입력 액션 이벤트들을 메세지 출력하는 노드와 연결하여 매핑한 키를 눌러서 잘 출력이 되는지 확인해보면 된다.
'언리얼 + cpp' 카테고리의 다른 글
언리얼C++ 6일차(애니메이션 블루프린트, 스테이트 머신, Control Rig) (0) | 2025.09.19 |
---|---|
언리얼C++ 5일차(액션 바인딩, 행동 함수 구현) (0) | 2025.09.18 |
언리얼C++ 5일차(GameMode) (0) | 2025.09.18 |
언리얼C++ 3일차(리플렉션 시스템) (0) | 2025.09.16 |
언리얼C++ 2일차(트랜스폼) (0) | 2025.09.15 |