언리얼 엔진에서 GameplayTag 로 Enhanced Input을 사용하기 위해서는 준비해야할 것들이 많습니다.
이렇게 하면 키보드 입력->(Mapping Context)->InputAction->InputFunction 처럼 흘러가게 됩니다.
우선 GameplayTag 부터 차근차근 만들어보겠습니다.
/** On Header File **/
~_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(InputTag_Move);
~_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(InputTag_Look);
/** On cpp File **/
UE_DEFINE_GAMEPLAY_TAG(InputTag_Move, "InputTag.Move");
UE_DEFINE_GAMEPLAY_TAG(InputTag_Look, "InputTag.Look");
위와 같이 태그를 선언해줍니다.
여기서 선언한 태그들은 Edit->ProjectSetting->GameplayTags->게임플레이 태그 관리 에서 확인하실 수 있습니다.

Build.cs 파일의
PublicDependencyModuleNames.AddRange부분에EnhancedInput,GameplayTags가 포함되어 있는지 확인해야합니다.
프로젝트를 처음만들면 주어지는 IA_Move, IA_Look을 그대로 사용하셔도 좋습니다.
만약 없다면, 콘텐츠 드로어에서 마우스 우클릭 -> 입력 -> 입력 액션 으로 IA를 만드신 후에, 값 타입을 Axis2D 로 바꿔주시면 됩니다.
Move와 Look 모두 상하좌우를 이동해야하기 때문에 필요합니다.


IA를 만들고 MappingContext에 등록해줍니다.

/** Header File **/
protected:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
private:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "CharacterData", meta = (AllowPrivateAccess = "true"))
UDataAsset_InputConfig* InputConfigDataAsset;
/** PlayerBaseCharacter::SetupPlayerInputComponent **/
ULocalPlayer* LocalPlayer = GetController<APlayerController>()->GetLocalPlayer();
UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(LocalPlayer);
check(Subsystem);
Subsystem->AddMappingContext(InputConfigDataAsset->DefaultMappingContext, 0);
UPlayerInputComponent* LocalInputComponent = CastChecked<UPlayerInputComponent>(PlayerInputComponent);
LocalInputComponent->BindNativeInputAction(InputConfigDataAsset, PlayerGameplayTags::InputTag_Move, ETriggerEvent::Triggered, this, &ThisClass::Input_Move);
LocalInputComponent->BindNativeInputAction(InputConfigDataAsset, PlayerGameplayTags::InputTag_Look, ETriggerEvent::Triggered, this, &ThisClass::Input_Look);
EnhancedLocalPlayerInputSubsystem에 접근하여 AddMappingContext를 호출합니다.
여기서 보지못했던 InputConfigDataAsset 과 UPlayerInputComponent 가 나옵니다.
해당 클래스는 직접 만들어야 합니다.
/** HeaderFile **/
public:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
UInputMappingContext* DefaultMappingContext;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (TitleProperty="InputTag"))
TArray<FPlayerInputActionConfig> NativeInputActions;
UInputAction* FindNativeInputActionByTag(const FGameplayTag& InInputTag) const;
DefaultMappingContext : 시작할 때 등록할 MappingContext
NativeInputActions : 시작할 때 등록할 IAs
FPlyaerInputActionConfig : GameplayTag와 InputAction이 포함된 구조체
FindNative~ByTag : 위 배열을 돌며 Tag와 일치하는 IA 반환
/** HeaderFile **/
template<class UserObject, typename CallbackFunc>
inline void UPlayerInputComponent::BindNativeInputAction(const UDataAsset_InputConfig* InInputConfig, const FGameplayTag& InInputTag, ETriggerEvent TriggerEvent, UserObject* ContextObject, CallbackFunc Func)
{
check(InInputConfig);
if (UInputAction* FoundAction = InInputConfig->FindNativeInputActionByTag(InInputTag)) {
BindAction(FoundAction, TriggerEvent, ContextObject, Func);
}
}
여기에 입력받는 Func 는 함수를 호출하는 부분에서 구현하여 인자로 넘겨줍니다.
Move, Look 의 경우, 해당 함수의 파라미터로 FInputActionValue 를 받을 수 있으며, IA에서 Axis2D로 설정했으므로 Get<FVector2D>() 를 통해 입력값을 받아 처리할 수 있습니다.

해당 InputComponent 를 사용하려면 ProjectSetting 에서 설정해주어야합니다.
void APlayerBaseCharacter::Input_Move(const FInputActionValue& InputActionValue)
{
const FVector2D MovementVector = InputActionValue.Get<FVector2D>();
const FRotator MovementRotation(0.f, Controller->GetControlRotation().Yaw, 0.f);
if (MovementVector.Y != 0.f) {
const FVector ForwardDirection = MovementRotation.RotateVector(FVector::ForwardVector);
AddMovementInput(ForwardDirection, MovementVector.Y);
}
if (MovementVector.X != 0.f) {
const FVector RightDirection = MovementRotation.RotateVector(FVector::RightVector);
AddMovementInput(RightDirection, MovementVector.X);
}
}
void APlayerBaseCharacter::Input_Look(const FInputActionValue& InputActionValue)
{
const FVector2D LookAxisVector = InputActionValue.Get<FVector2D>();
if (LookAxisVector.X != 0.f) {
AddControllerYawInput(LookAxisVector.X);
}
if (LookAxisVector.Y != 0.f) {
AddControllerPitchInput(LookAxisVector.Y);
}
}
예를 들어, Input_Move 는 InputActionValue에서 화살표 입력을 FVector2D로 받습니다.
해당 입력은 상하좌우를 나타내며, AddMovementInput 함수로 움직임을 구현합니다.
여기까지 구현한 후에 전부 에셋으로 만든 후에 하나씩 설정합니다.


전부 설정해주면 캐릭터가 움직이는 모습을 확인하실 수 있습니다.

Enhanced Input Component와 GameplayTags를 활용하여 캐릭터가 입력을 통해 움직일수 있도록 구현했습니다.
다음에는 움직임에 따라 캐릭터가 자연스럽게 움직일 수 있도록 애니메이션을 추가해보겠습니다.