PART 5 · 강의 6/7

Enhanced Input 시스템

UE5 기본 입력 시스템과 GAS 연동

01

Enhanced Input 개요

UE 5.1부터 기본 입력 시스템

Enhanced Input System은 UE 5.1부터 기본 입력 시스템으로 채택되었습니다. 기존 Input System 대비 더 유연하고 모듈화된 입력 처리가 가능합니다.

Input Action

입력 정의

Modifiers

값 변환

Triggers

발동 조건

Mapping Context

키 바인딩

Enhanced Input의 장점
  • Context 기반 — 상황에 따라 입력 매핑을 동적으로 변경 가능
  • Modifier 체인 — 입력 값을 파이프라인으로 가공
  • 데이터 주도 — 입력 액션과 매핑을 에셋으로 관리
  • 멀티플랫폼 — 키보드, 게임패드, 터치 동시 지원
02

Input Action 정의

다양한 입력 타입과 트리거

Trigger 유형

Trigger 설명 사용 예시
Started 버튼 누른 순간 점프, 공격
Triggered 누르는 동안 매 프레임 이동, 카메라
Completed 버튼 뗀 순간 점프 중지, 차징 해제
Canceled 액션 취소됨 차징 취소
Ongoing 조건 만족 중 홀드 진행 중

Modifier 유형

Negate

값을 반전합니다. 예: S키를 W와 같은 액션에 바인딩하면서 후진으로 사용

Swizzle Input Axis Values

축을 교환합니다. YXZ → XYZ 등

Dead Zone

임계값 이하 입력을 무시합니다. 게임패드 스틱의 드리프트 방지

Scalar

값을 배수로 조정합니다. 감도 조절에 활용

03

PlayerController 구현

입력 바인딩 및 처리

MyPlayerController.h #pragma once #include "CoreMinimal.h" #include "GameFramework/PlayerController.h" #include "InputActionValue.h" #include "MyPlayerController.generated.h" class UInputMappingContext; class UInputAction; UCLASS() class MYGAME_API AMyPlayerController : public APlayerController { GENERATED_BODY() public: AMyPlayerController(); protected: virtual void BeginPlay() override; virtual void SetupInputComponent() override; // Input Mapping Context UPROPERTY(EditDefaultsOnly, Category = "Input") UInputMappingContext* DefaultMappingContext; // Input Actions UPROPERTY(EditDefaultsOnly, Category = "Input") UInputAction* MoveAction; UPROPERTY(EditDefaultsOnly, Category = "Input") UInputAction* LookAction; UPROPERTY(EditDefaultsOnly, Category = "Input") UInputAction* JumpAction; UPROPERTY(EditDefaultsOnly, Category = "Input") UInputAction* AttackAction; UPROPERTY(EditDefaultsOnly, Category = "Input") UInputAction* InteractAction; UPROPERTY(EditDefaultsOnly, Category = "Input") UInputAction* InventoryAction; // Input Handlers void HandleMove(const FInputActionValue& Value); void HandleLook(const FInputActionValue& Value); void HandleJump(); void HandleStopJump(); void HandleAttack(); void HandleInteract(); void HandleInventory(); };
MyPlayerController.cpp #include "MyPlayerController.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" #include "InputMappingContext.h" #include "MyCharacter.h" AMyPlayerController::AMyPlayerController() { } void AMyPlayerController::BeginPlay() { Super::BeginPlay(); // Input Mapping Context 추가 if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>( GetLocalPlayer())) { if (DefaultMappingContext) { // Priority 0: 기본 매핑 Subsystem->AddMappingContext(DefaultMappingContext, 0); } } } void AMyPlayerController::SetupInputComponent() { Super::SetupInputComponent(); if (UEnhancedInputComponent* EnhancedInput = Cast<UEnhancedInputComponent>(InputComponent)) { // 이동 (Triggered: 누르는 동안 계속) if (MoveAction) { EnhancedInput->BindAction( MoveAction, ETriggerEvent::Triggered, this, &AMyPlayerController::HandleMove); } // 카메라 (Triggered) if (LookAction) { EnhancedInput->BindAction( LookAction, ETriggerEvent::Triggered, this, &AMyPlayerController::HandleLook); } // 점프 (Started: 누를 때, Completed: 뗄 때) if (JumpAction) { EnhancedInput->BindAction( JumpAction, ETriggerEvent::Started, this, &AMyPlayerController::HandleJump); EnhancedInput->BindAction( JumpAction, ETriggerEvent::Completed, this, &AMyPlayerController::HandleStopJump); } // 공격 (Started: 한 번만) if (AttackAction) { EnhancedInput->BindAction( AttackAction, ETriggerEvent::Started, this, &AMyPlayerController::HandleAttack); } // 상호작용 if (InteractAction) { EnhancedInput->BindAction( InteractAction, ETriggerEvent::Started, this, &AMyPlayerController::HandleInteract); } // 인벤토리 if (InventoryAction) { EnhancedInput->BindAction( InventoryAction, ETriggerEvent::Started, this, &AMyPlayerController::HandleInventory); } } }
04

입력 핸들러 구현

GAS 및 캐릭터 연동

MyPlayerController.cpp (계속) void AMyPlayerController::HandleMove(const FInputActionValue& Value) { // Vector2D: X=Right, Y=Forward const FVector2D MovementVector = Value.Get<FVector2D>(); if (AMyCharacter* MyCharacter = Cast<AMyCharacter>(GetPawn())) { // 카메라 방향 기준 이동 const FRotator Rotation = GetControlRotation(); const FRotator YawRotation(0, Rotation.Yaw, 0); const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); MyCharacter->AddMovementInput(ForwardDirection, MovementVector.Y); MyCharacter->AddMovementInput(RightDirection, MovementVector.X); } } void AMyPlayerController::HandleLook(const FInputActionValue& Value) { const FVector2D LookVector = Value.Get<FVector2D>(); AddYawInput(LookVector.X); AddPitchInput(LookVector.Y); } void AMyPlayerController::HandleJump() { if (ACharacter* MyCharacter = GetCharacter()) { MyCharacter->Jump(); } } void AMyPlayerController::HandleStopJump() { if (ACharacter* MyCharacter = GetCharacter()) { MyCharacter->StopJumping(); } } void AMyPlayerController::HandleAttack() { if (AMyCharacter* MyCharacter = Cast<AMyCharacter>(GetPawn())) { if (UAbilitySystemComponent* ASC = MyCharacter->GetAbilitySystemComponent()) { // GameplayTag로 어빌리티 활성화 FGameplayTagContainer TagContainer; TagContainer.AddTag( FGameplayTag::RequestGameplayTag( FName("Ability.Attack.Melee"))); ASC->TryActivateAbilitiesByTag(TagContainer); } } } void AMyPlayerController::HandleInteract() { if (AMyCharacter* MyCharacter = Cast<AMyCharacter>(GetPawn())) { MyCharacter->TryInteract(); } } void AMyPlayerController::HandleInventory() { // UI 토글 if (AMyHUD* HUD = Cast<AMyHUD>(GetHUD())) { HUD->ToggleInventory(); } }
Context 전환

UI가 열리면 UIMappingContext를 추가하고 DefaultMappingContext의 우선순위를 낮추어 입력 처리를 전환할 수 있습니다.

SUMMARY

핵심 요약

  • Input Action — 입력의 논리적 의미를 정의하는 에셋 (이동, 점프, 공격 등)
  • Input Mapping Context — 실제 키와 Input Action을 연결하는 매핑
  • Trigger Event — Started, Triggered, Completed 등 입력 상태에 따른 이벤트
  • Modifier — 입력 값을 가공하는 파이프라인 (Dead Zone, Negate, Scalar 등)
  • GAS 연동 — 공격 등의 입력을 GameplayTag로 어빌리티와 연결
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: Enhanced Input 기본 설정

UInputAction과 UInputMappingContext를 에디터에서 생성하세요. IA_Move, IA_Look, IA_Attack, IA_Interact, IA_Inventory를 정의하고, DefaultMappingContext에 키 바인딩하세요.

실습 2: Input Action 바인딩

SetupPlayerInputComponent()에서 UEnhancedInputComponent::BindAction()으로 각 액션을 바인딩하세요. ETriggerEvent::Started, Triggered, Completed를 구분하여 한 번 누르기, 누르고 있기 패턴을 구현하세요.

심화 과제: 컨텍스트 기반 입력 전환

전투, 인벤토리 UI, 대화, 탈것 탑승 등 상황에 따라 UEnhancedInputLocalPlayerSubsystem::AddMappingContext()/RemoveMappingContext()로 입력 매핑을 동적으로 전환하는 시스템을 구현하세요.