UE Input 2에서 이어지는 내용


Single Source of Truth

모든 시스템은 현재 상태를 직접 판단하지 말고 State Machine을 기준으로 판단해야 한다.

void OnAttack()
{
    if (StateMachine->GetCurrentState() != ECleaningState::Idle)
    {
        return;
    }

    Attack();
}
void TakeDamage(float Damage)
{
    if (StateMachine->GetCurrentState() == ECleaningState::Cleaning)
    {
        return;
    }

    Health -= Damage;
}

State Machine을 기준으로 삼으면 UI, 전투, 입력, 애니메이션 시스템이 서로 다른 상태를 바라보는 문제를 줄일 수 있다.


설계 원칙

단일 책임 원칙

각 클래스는 하나의 책임만 가져야 한다.

클래스 책임
UContextManagerComponent 입력 Context 관리
UCleaningStateMachine 행동 상태와 전이 관리
AEnhancedChallengeCharacter 입력 위임 및 시스템 연결

나쁜 구조는 다음처럼 하나의 함수에 모든 책임이 모이는 형태다.

void ACharacter::OnInteract()
{
    if (CurrentMode == CleaningMode)
    {
        PlayMontage();
        UpdateHUD();
        PlaySound();
    }
}

좋은 구조는 입력 해석, 상태 판단, 실제 표현을 분리하는 것이다.

ContextManager
  → 현재 입력 모드 판단

StateMachine
  → 현재 행동 가능 여부 판단

Character
  → 각 시스템 호출

개방-폐쇄 원칙

기능 확장에는 열려 있고, 기존 코드 수정에는 닫혀 있어야 한다.

새로운 Context를 추가할 때 기존 입력 함수를 계속 수정하는 구조는 좋지 않다.
Enhanced Input과 ContextManager를 사용하면 새로운 Context를 추가하는 방식으로 확장할 수 있다.

enum class EGameplayContext : uint8
{
    Default,
    FloorCleaning,
    WindowCleaning,
    Fishing
};

추가 절차는 다음과 같다.

1. IMC_Fishing 생성
2. EGameplayContext::Fishing 추가
3. ContextMappings에 등록

기존 입력 처리 코드를 크게 수정하지 않고 새로운 입력 모드를 추가할 수 있다.


의존성 역전 원칙

구체적인 키 입력에 의존하지 않고, 추상적인 입력 의도에 의존해야 한다.

나쁜 방식

if (IsKeyPressed(EKeys::E))
{
    CleanFloor();
}

이 코드는 키보드 E 키에 직접 의존한다.
게임패드, VR 컨트롤러, 키 리바인딩을 지원하려면 코드 수정이 필요하다.

좋은 방식

void OnInteract(const FInputActionValue& Value)
{
    ExecuteInteraction();
}

OnInteract는 어떤 키가 눌렸는지 모른다.
단지 “상호작용 의도”가 발생했다는 사실만 처리한다.

멀티 도구 시스템

enum class EGameplayContext : uint8
{
    FloorCleaning,
    WindowCleaning,
    CarCleaning,

    Sword,
    Bow,
    Magic,

    OnFoot,
    InCar,
    InBoat
};

각 Context마다 다른 IMC를 등록하면, 같은 입력이라도 상황에 따라 완전히 다른 조작 체계를 만들 수 있다.

복합 State Machine

class ACharacter
{
    UCleaningStateMachine* CleaningState;
    UCombatStateMachine* CombatState;
    UMovementStateMachine* MovementState;
};
void OnAttack()
{
    if (CombatState->CanAttack() &&
        CleaningState->IsIdle() &&
        MovementState->CanAct())
    {
        Attack();
    }
}

여러 FSM을 병렬로 운용하면 전투, 이동, 상호작용 상태를 분리해서 관리할 수 있다.

데이터 주도 설계

USTRUCT()
struct FContextDefinition
{
    EGameplayContext ContextType;
    UInputMappingContext* IMC;
    TArray<UAnimMontage*> AvailableActions;
    float StaminaCost;
};

Context 정의를 Data Asset으로 분리하면 디자이너가 코드 수정 없이 입력 모드, 행동, 비용 등을 조정할 수 있다.


Input 내용 요약

Enhanced Input System은 기존 입력 방식처럼 키 입력을 직접 함수에 연결하고 내부에서 조건문으로 분기하는 구조를 개선한다.

키 입력
  ↓
InputAction
  ↓
Input Mapping Context
  ↓
ContextManager
  ↓
StateMachine
  ↓
실제 행동

각 요소의 역할은 명확히 분리된다.

요소 역할
InputAction 입력 의도 정의
Modifier 입력값 변환
Trigger 입력 발동 조건 판단
Input Mapping Context 키와 InputAction 연결
Enhanced Input Subsystem 활성 Context 관리
ContextManager 게임 상황 의미 부여
StateMachine 현재 행동 가능 여부 판단

결론적으로 Enhanced Input을 제대로 활용하려면 단순히 BindAction을 사용하는 것에서 끝나면 안 된다.
InputAction, Mapping Context, ContextManager, State Machine을 함께 설계해야 확장 가능하고 유지보수하기 쉬운 입력 구조를 만들 수 있다.

반응형

'Unreal Engine' 카테고리의 다른 글

언리얼 레퍼런스  (0) 2026.06.29
DataTable, DataAsset  (0) 2026.06.26
UE Input 2  (0) 2026.06.24
UE Input 1  (0) 2026.06.23
GameplayTag Static vs GameplayTag Extern  (0) 2026.06.22