언리얼 엔진 5의 Enhanced Input 시스템은 기존의 입력 시스템(Input System)을 대체하여 보다 유연하고 강력한 입력 처리를 제공한다. 이 시스템은 다양한 입력 디바이스를 통합 관리하고, 더 복잡한 입력 매핑과 처리 로직을 지원한다.
Enhanced Input의 주요 개념
- Input Mapping Contexts:
- 입력 맵핑 컨텍스트는 여러 입력 액션(Input Actions)을 그룹화하는 역할을 한다.
- 특정 상황이나 상태에서 활성화될 수 있으며, 여러 컨텍스트를 겹쳐 사용할 수 있다.
- 예를 들어, 걷기 상태와 운전 상태에 따라 다른 입력 맵핑 컨텍스트를 사용할 수 있다.
- Input Actions:
- 입력 액션은 단일 입력 이벤트(키 누르기, 마우스 클릭 등)를 나타낸다.
- 디지털 입력(키보드, 버튼)과 아날로그 입력(조이스틱, 트리거) 모두 지원한다.
- 트리거 조건(Pressed, Released, Held 등)과 같은 다양한 입력 조건을 설정할 수 있다.
- Input Modifiers:
- 입력 값에 변형을 가하는 역할을 한다.
- 예를 들어, 축소, 확대, 반전 등의 변형을 적용할 수 있다.
- Input Triggers:
- 입력 이벤트가 트리거될 조건을 정의한다.
- 예를 들어, 버튼이 눌렸을 때, 버튼이 일정 시간 동안 눌려있을 때 등의 조건을 설정할 수 있다.
위와같은 개념을 기반으로 언리얼 엔진의 Enhanced Input 시스템은 더 유연하고 강력한 입력 처리를 가능하게 한다. 이를 통해 개발자는 다양한 입력 장치와 복잡한 입력 시나리오를 보다 쉽게 관리할 수 있다.
Enhanced Input 시스템은 Input Mapping Context, Input Action, Input Modifiers, Input Triggers와 같은 개념을 통해 입력을 구조화하고, 블루프린트나 C++ 코드에서 이를 활용하여 게임 내 입력 로직을 구현할 수 있다.
설정 및 사용 방법
콘텐츠 브라우저에서 우클릭을 통해 다음과 같은 에셋들을 생성할 수 있다.
- Input Mapping Context 생성:
- 입력 맵핑 컨텍스트를 생성하여, 해당 컨텍스트 내에서 사용할 입력 액션을 정의한다.
- 컨텍스트는 주로 에디터의 콘텐츠 브라우저에서 생성할 수 있다.
- Input Action 생성:
- 각 입력 액션을 생성하고, 입력 장치 및 입력 유형을 정의한다.
- 예를 들어, "MoveForward" 입력 액션을 생성하고, 키보드의 "W" 키와 매핑할 수 있다.
- Input Mapping Context에 Input Action 추가:
- 생성한 입력 액션을 입력 맵핑 컨텍스트에 추가한다.
- 각 액션에 대해 트리거 조건과 모디파이어를 설정할 수 있다.
- C++ 또는 블루프린트에서 입력 처리:
- 생성한 입력 맵핑 컨텍스트와 입력 액션을 사용하여, 캐릭터나 플레이어 컨트롤러 클래스에서 입력 처리를 구현한다.
예제: PlayerController에서 입력받기
- Input Mapping Context 및 Input Action 생성:
- 콘텐츠 브라우저에서 "Input Mapping Context"와 "Input Action" 에셋을 생성한다.
- 각 Input Action에 대해 키 매핑을 설정한다.
- PlayerController 설정:
- 블루프린트 또는 C++ 코드에서 플레이어 컨트롤러 클래스를 설정하고, 생성된 입력 맵핑 컨텍스트를 활성화한다.
- Input 이벤트 처리:
- 플레이어 컨트롤러나 캐릭터 블루프린트에서 입력 이벤트를 처리한다.
- 블루프린트에서 Enhanced Input Component를 사용하여 입력 액션에 대한 콜백을 설정한다.
void AMyPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
// Add the mapping context
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
// Bind input actions
InputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyPlayerController::Move);
}
void AMyPlayerController::Move(const FInputActionValue& Value)
{
FVector2D MovementVector = Value.Get<FVector2D>();
// Movement logic here
}
예제: Character클래스 에서 입력받기고 InputValue ( (ex)1D float Axis)를 사용하여 처리해보기
Enhanced Input 시스템에서 1D float Axis 값을 사용하여 애니메이션에 활용하려면, 입력 액션을 BindAction에 바인딩할 때 적절한 파라미터를 전달해야 한다. 특히, float 값을 전달할 때 BindAction 호출 시에 값이 제대로 전달되는지 확인해야 한다.
EnhancedInputComponent의 BindAction 메서드는 IInputActionInstance를 매개변수로 사용하므로, 이를 활용하여 축 값을 얻을 수 있다.
먼저 헤더파일에서 해야할 기본적인 것들이 있다
- #include "InputActionValue.h"를 추가하여 FInputActionValue를 사용할 수 있도록 한다.
- 바인딩을 하기위해 사용할 TriggerGraspAnimRight 함수의 매개변수를 const FInputActionValue&로 변경한다.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "InputActionValue.h"
#include "VRCharacter.generated.h"
UCLASS()
class MYPROJECT_API AVRCharacter : public ACharacter
{
GENERATED_BODY()
public:
AVRCharacter();
protected:
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
USkeletalMeshComponent* HandMesh;
// Function to handle grasp animation
void TriggerGraspAnimRight(const FInputActionValue& Value);
};
다음으로, 소스 파일에서 함수 정의를 수정하고 입력 액션을 바인딩한다.
- TriggerGraspAnimRight 함수에서 Value.Get<float>()를 사용하여 float 값을 추출한다.
- SetupPlayerInputComponent 함수에서 EnhancedInputComponent를 캐스팅하여 입력 액션을 바인딩한다.
#include "VRCharacter.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "VRHandAnimInstance.h"
AVRCharacter::AVRCharacter()
{
// Set this character to call Tick() every frame.
PrimaryActorTick.bCanEverTick = true;
// Initialize the HandMesh component
HandMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("HandMesh"));
HandMesh->SetupAttachment(RootComponent);
}
void AVRCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
// Bind the input action
EnhancedInputComponent->BindAction(IAGraspAnimRight, ETriggerEvent::Triggered, this, &AVRCharacter::TriggerGraspAnimRight);
}
}
void AVRCharacter::TriggerGraspAnimRight(const FInputActionValue& Value)
{
float InAxisValue = Value.Get<float>(); // Extract the float value from the input action
UVRHandAnimInstance* HandAnimInstance = Cast<UVRHandAnimInstance>(HandMesh->GetAnimInstance());
if (HandAnimInstance)
{
HandAnimInstance->SetGrapPoseAlpha(InAxisValue);
UE_LOG(LogTemp, Warning, TEXT("GrapPoseAlpha: %f"), HandAnimInstance->GetGrapPoseAlpha());
}
}
'게임엔진 > Unreal' 카테고리의 다른 글
[Unreal] 애님 블프 Idle 애니메이션 무작위 실행 (0) | 2024.01.27 |
---|---|
[Unreal] C++ error C2018 : '' 문자를 인식할 수 없습니다 오류 해결 (0) | 2024.01.16 |
[Unreal] C++ 변환할 수 없습니다 오류 해결 (0) | 2024.01.16 |
[Unreal] Reflection (리플렉션) (0) | 2023.12.04 |
[Unreal] 비동기 에셋 로딩 (0) | 2023.12.04 |