본문 바로가기

Unreal/언리얼 엔진 5로 개발하는 멀티플레이어 게임(Book)

[Unreal] US_Character.cpp 입력 연결 코드 분석(입력)

분석하기에 앞서 헤더 파일은 생략하기로 하였다. 그 이유는 이전 글과 유사한 점이 많기 때문이다.

입력 처리 단계

언리얼에서 입력을 하기 위해 사용한 EnhancedInputComponent.h, EnhancedInputSubsystems.h의 역할은 무엇일까?

언리얼 문서를 살펴보면 플레이어 입력을 액션 매핑과 축 매핑으로 나뉜다. 둘로 나눠진 매핑을 연결하기 위해 C++ 코드를 작성하는데 이 역할을 EnhancedInputComponent.h, EnhancedInputSubsystems.h가 한다.

요약하자면, 입력 장치에서 발생한 입력은 EnhancedInputSubsystems를 통해 현재 활성 컨텍스트로 전달되고, 이후 바인딩된 EnhancedInputComponent에서 처리된다.

EnhancedInputSubsystems.h

US_Character.cpp

void AUS_Character::BeginPlay()
{
    Super::BeginPlay();
    if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
    {
        if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
        {
            Subsystem->AddMappingContext(DefaultMappingContext, 0);
        }
    }
}

 

 

[UE5] TIL - 14 <AController, APlayerController, Cast>

AController가 APlayerController의 상위 타입의 오브젝트이다. 그러니 AController 로 선언한 변수에 APlayerController를 할당할 수 없다. Cast 함수를 써서 할당해주어야한다.

velog.io

 

먼저 코드를 이해하기 위해 APlayerController와 Cast를 위 글을 참고하면 좋다.

  • APlayerController: 폰을 컨트롤하기 위한 클래스이다. Cast를 사용하는 이유는 Controller가 선언된 곳을 보면 TObjectPtr<AController> Controller로 되어 있다. 이는 APlayerController보다 상위이기 때문에 Cast를 통해 변환해 준다.
  • UEnhancedInputLocalPlayerSubsystem: 이해하기 위해서는 언리얼 문서를 보는 것이 가장 빠르다. 결론적으로 말하면 로컬 플레이어 입력 하위 시스템으로, 로컬 플레이어에 관한 입력 시스템을 관리한다고 생각하는 것이 맞는 것 같다. 해당 클래스를 선언하는 이유는 코드를 보면 PlayerController의 UEnhancedInputLocalPlayerSubsystem을 사용하기 위함으로 보인다.
  • ULocalPlayer::GetSubsystem: 코드를 보면 ULocalPlayer의 컨트롤을 가져오고 Subsystem을 초기화한다.
  • Subsystem->AddMappingContext(DefaultMappingContext, 0): 우리가 만든 DefaultMappingContext을 맵핑하여 시스템에 연결하는 역할을 한다. 0은 우선순위로, 낮을수록 우선순위가 높다.

결론적으로 컨트롤러가 플레이어 컨트롤러(APlayerController)를 확인 후 플레이어 로컬 서브 시스템(UEnhancedInputLocalPlayerSubsystem)을 가져오고 특정 입력 매핑 컨텍스트(DefaultMappingContext)를 추가하여 입력처리를 활성화 한다.

 

EnhancedInputComponent.h

활성화된 입력처리에 함수를 바인딩해주기 위해 SetupPlayerInputComponent함수에 같은 코드를 작성한다.

 

US_Character.cpp

void AUS_Character::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
    {
        EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AUS_Character::Move);
        EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AUS_Character::Look);
        EnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Started, this, &AUS_Character::Interact);
        EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Started, this, &AUS_Character::SprintStart);
        EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Completed, this, &AUS_Character::SprintEnd);
    }
}

 

  • EnhancedInputComponent->BindAction: 입력 액션을 특정 함수에 연결한다.
  • ETriggerEvent::Triggered: 입력 이벤트의 트리거 상태를 지정한다. 'Triggered'는 액션이 완전히 활성화되었을 때를 의미한다.

추가적으로 아래 글을 보충하여 읽으면 좋다.

 

[Unreal] 향상된 입력

C++ 에서 향상된 입력 사용모듈EnhancedInput헤더#include "EnhancedInputSubsystems.h" 그 외 필요 헤더UInputMappingContext#include "InputMappingContext.h"FInputActionInstance#include "InputAction.h"UEnhancedInputComponent#include "Enhan

morningcopy.tistory.com