개요

런타임에 Pawn 을 제거 → 재스폰하면서 Actor 가 소유한 InputComponent 는 제거되어 InputAction

을 바인딩한 것도 모두 제거된다. 하지만 InputMappingContext 는

UEnhancedInputLocalPlayerSubSystem 에 남아있어 직접 IMC 를 제거해줘야 했다.

왜 IMC 는 제거하지 않을까?


1.플레이어의 커스텀 키 설정에 대응하기 위해서

  • 플레이어가 변경한 키 설정은 영구적으로 유지되어야 한다.
  • 캐릭터가 바뀌거나 죽어도 키 설정은 그대로 유지되어야 한다.
  • 예를 들어 플레이어가 E키를 R키로 변경하면
    • 캐릭터가 죽었을 때, IMC 가 사라지면 재설정 해야 한다...
    • 변경 전: E키 → IA_SKILL → FireBall()
    • 변경 후: R키 → IA_SKILL → FireBall()
  • R키에 IA_SKILL 가 매핑되었다는 것이 사라지면 안된다!

2. 탑승 시스템이나, 다른 캐릭터에 Posses 할 때 사라지면 안됨

// 걸어다니기
Player의 IMC: W,A,S,D = IA_Move
Character->InputComponent: IA_Move → Walk()

// 말 탑승
Horse->Possess(); // Character는 Unpossess됨
Player의 IMC: W,A,S,D = IA_Move (동일!)
Horse->InputComponent: IA_Move → HorseWalk()

// 말에서 내림
Character->Possess(); // 다시 조종
Player의 IMC: W,A,S,D = IA_Move (여전히 동일!)
Character->InputComponent: IA_Move → Walk()
  • 캐릭터/탈것/상황이 바뀌어도 입력 방식은 일관되어야 한다!
  • 만약 IMC 가 사라진다면, 갑자기 말에 탔는데 조종이 안되는 문제가 생길 수 있다.
    • 다시 IMC 를 설정해줘야 한다.
    • 그래서 효율성의 장점도 있다!

왜 InputActionBinding은 제거되어도 상관없나?

  • IMC에 IA_SKILL 매핑만 되어있다면, 각자의 캐릭터가 스폰 시 자신의 함수를 바인딩하면 된다.
    • CharacterA: IA_SKILL → FireBall() CharacterB: IA_SKILL → Storm() CharacterC: IA_SKILL → Heal()

  • SetupPlayerInputComponent 함수 안에서 BindAction 으로 다시 바인딩된다.
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* Input)
{
    // 캐릭터가 생성될 때마다 자동으로 호출됨
    UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(Input);
    
    // Player의 IMC는 이미 R키 = IA_SKILL로 설정되어 있음
    // 여기서는 IA_SKILL → 내 함수만 연결하면 됨
    EI->BindAction(SkillAction, ETriggerEvent::Started, this, &AMyCharacter::UseSkill);
}

고민했던 부분

캐릭터를 선택하면 해당 캐릭터 Definition 을 가져와 Pawn 을 재성성하고

GameFeature 와 기본 입력 세팅을 진행하도록 만들었다.


Movement_Standard 피처 에서 IMC_Movement_Standard 와 InputAction 을 바인딩하고 있다.


플레이 테스트하며 기존의 IMC 도 남아있고, 신규 IMC도 추가되는 것을 볼 수 있었고,

바인딩한 InputAction 들은 InputComponent 가 소유하기 때문에 사라졌었다.


캐릭터를 계속 변경하면 기존의 IMC 가 계속 추가되나? 싶었는데

내부적으로 IEnhancedInputSubsystemInterface 의 AddInputMappingContext 함수에서 PlayerInput->AppliedInputContextData.Add(MappingContext, { Priority });

Map 을 사용해서 덮어써진다.


이 때 생긴 의문을 정리해보았다.


*Ehanced Input System 처리 방식 정리

Enhanced Input System은 입력 처리를 두 단계로 분리한다


1단계: 입력 매핑 (InputMappingContext)

"W키를 누르면 'IA_Move' 액션이 발생한다"

소유자: LocalPlayer (UEnhancedInputLocalPlayerSubsystem)
생명주기: 플레이어가 게임에 있는 동안 지속
역할: 입력 매핑 규칙 정의

2단계: 입력 처리 (InputActionBinding)

"'IA_Move' 액션이 발생하면 이 캐릭터가 앞으로 이동한다"

소유자: Actor (InputComponent)
생명주기: 액터와 함께 생성/제거
역할: 입력에 대한 구체적인 반응 정의