#1. 개념
1. Enhanced Input
Enhanced Input 시스템은 Unreal의 전통적인 입력 시스템으로부터 확장하여 더욱 유연하고, 세밀한 입력 관련 처리를 가능케 하는 입력 시스템입니다. Enhanced Input을 통해 Unreal 사용자는 입력 관련 원본 수치에 대하여
radial dead zones, chorded actions, contextual input, and prioritization 등의 복잡한 작업들을 "Asset-Based Environment"에서 수행하며, 이는 기존 코드에 대한 변경, 혹은 추가적인 하드 코딩 작업 없이도 가능합니다.
2. Input Action(IA)
Input Action은 Enhanced Input 시스템과 프로젝트 코드의 소통 관계에서 링크 역할을 수행합니다. IA는 개념적으로 액션 매핑 혹은 축 매핑과 동일하며, IA는 이들과 달리 Data Asset 유형입니다.
3. Input Mapping Context(IMC)
Input Mapping Context는 특정 IA 혹은 두 개 이상의 IA를 발동시킬 조건들을 정의합니다. 이를 통해, 사용자의 입력과 IA를 매핑시키고, 동적으로 추가, 제거, 우선순위 결정을 수행합니다. 각 IMC는 이에 관련된 모든 IA를 populate 하여, 사용 환경에 따라서 여러 IMC를 정의할 수 있습니다. 이처럼, 여러 IMC를 활용함으로써, IA 간 상호배제를 통해 사용자 입력 간 충돌을 방지하고, 사용자 입력에 대응되는 적절한 IA 활성화가 가능해집니다. 이때, IMC는 올바른 IA 활성화를 위한 원본 입력 값의 수치 조정 및 조건 합치 여부를 확인하기 위해 "Modifier"와 "Trigger"를 활용합니다.
4. Modifier
Modifier는 사용자 기기로부터 전달 받은 원본 입력 값의 수치 조정을 수행합니다. IMC는 사용자의 원본 입력에 대하여 올바른 IA 활성화 동작을 연계하기 위해 몇 가지 Modifier들을 정의합니다.
5. Trigger
Trigger는 Modifer 목록들을 거쳐 최종적으로 전달받은 입력 값에 대하여 몇 가지 조건 합치 여부를 체크하고, 최종적으로 IA를 활성화할 것인지 결정합니다. Trigger는 IA 활성화를 위한 최소 값 혹은 패턴 만족 여부(짧은 탭, 홀드... etc)를 체크합니다. Enhanced Input 시스템은 Trigger를 활용해 사용자 입력 패턴을 확인하기 위한 Delay 혹은 Timer 등의 추가적인 코드 작성이 생략되어, 더 효율적인 Input System을 설계하는 것이 가능합니다.
#2. Enhanced Input을 통해 방향 입력과 시야 방향 입력 설정
2. IA 형식의 블루프린트 클래스 생성
3. IA_Move
캐릭터 이동 방향을 설정하는 IA는 일반적으로 2D축(FVector2D)를 값 타입으로 설정합니다.
4. IA_Look
시야 방향을 설정하는 입력은 일반적으로 2D축(FVector2D)를 값 타입으로 설정합니다.
3. IMC 블루프린트에 IA 추가 및 키 설정
[ 왼손 좌표계 ]
1. "W" 키 -> NoModifier -> IA_Move(Axis2D)
2. "S" 키 -> Modifier_1 : Negate(-X) -> IA_Move(Axis2D)
3. "D" 키 -> Modifier_1 : Swizzle(YXZ) -> IA_Move
4. "A" 키 -> Modifer_1 : Swizzle(YXZ) -> Modifier_2 : Negate(-Y) -> IA_Move
[ 오른손 좌표계 ]
마우스 2D XY축 -> Modifier_1 : Negate(-Y) -> IA_Look
[Modifier]
1. Negate : 원본 입력 값에 대하여 특정 요소를 (-)값으로 반전시킨다.
2. Swizzle : 일반적으로, 2D축 값 타입으로 설정된 IA의 경우 입력 값이 'X'값에 우선적으로 할당된다.
이때, Swizzle은 원본 입력 값이 2D축 값 타입의 어떤 요소에 우선적으로 할당될 것인지 결정합니다.
IMC에 IA를 추가하고, 어떠한 사용자 입력에 해당 IA를 연결할 것인지 결정합니다. 이때, 각 키에 대하여 Modifier와 Trigger를 설정해 줍니다. 여기서 "Negate"와 "Swizzle"은 Modifier입니다.
4. CharacterBase.h : IA와 IMC의 데이터 멤버 선언
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "InputActionValue.h"
#include "EnahancedInputSystemCharacter.generated.h"
UCLASS(config=Game)
class AEnahancedInputSystemCharacter : public ACharacter
{
//...
/** MappingContext */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputMappingContext* DefaultMappingContext;
/** Move Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* MoveAction;
/** Look Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* LookAction;
public:
AEnahancedInputSystemCharacter();
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// To add mapping context
virtual void BeginPlay();
protected:
void Move(const FInputActionValue& Value);
void Look(const FInputActionValue& Value);
//...
};
캐릭터 객체에 할당할 IA들과 IMC를 멤버로 선언하고, 각 IA를 정의할 멤버 함수들을 선언합니다.
4. CharacterBase::BeginPlay()
void AEnahancedInputSystemCharacter::BeginPlay()
{
// Call the base class
Super::BeginPlay();
/*
* @목적 : Enhanced Input을 캐릭터에 적용합니다.
* @설명
* 1. PlayerController를 가져옵니다.
* 2. PlayerCOntroller->LocalPlayer를 GetSubsystem의 인자로 전달해, UEnhancedInputLocalPlayerSubsystm 형식의 EI의 하위 시스템을 가져옵니다.
* 3. EI의 AddMappingContext 함수에 전달해, 최종적으로 IMC를 EI에 추가합니다.
*/
//Add Input Mapping Context
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
{
Subsystem->AddMappingContext(DefaultMappingContext, /*Priority:*/0);
}
}
}
BeginPlay() 함수에서 데이터 멤버로 선언된 IMC 객체를 Enhanced Input 하위 시스템에 추가해줍니다.
5. CharacterBase::SetupPlayerInputComponent()
void AEnahancedInputSystemCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
{
EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AEnahancedInputSystemCharacter::Move);
EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AEnahancedInputSystemCharacter::Look);
}
}
캐릭터 객체의 Enhanced Input Component를 통해 특정 IA 이벤트에 콜백 함수들을 바인딩해줍니다.
6. CharacterBase::Move() : IA_Move 이벤트에 바인딩된 콜백 함수 정의
void AEnahancedInputSystemCharacter::Move(const FInputActionValue& Value)
{
const FVector2D MovementVector = Value.Get<FVector2D>();
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation = FRotator(0.f, Rotation.Yaw, 0.f);
// Forward, Backward
const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(ForwardDirection, MovementVector.X);
// Right, Left
const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(RightDirection, MovementVector.Y);
}
IA_Move의 값 타입은 FVector2D이며, 앞, 뒤, 오른쪽, 그리고 왼쪽 이동을 정의하기 위한 코드를 작성합니다.
7. CharacterBase::Look() : IA_Look 이벤트에 바인딩 된 콜백 함수 정의
/*
* @목적 : 카메라의 방향 설정
* @설명
* 1. 마우스 2D XY축은 오른손 좌표계, X가 오른쪽 왼쪽 + Y가 앞쪽 뒤쪽
* 2. 따라서, X값은 Yaw 회전, Y값은 Pitch 회전에 각각 더해준다.
*/
void AEnahancedInputSystemCharacter::Look(const FInputActionValue& Value)
{
const FVector2D LookAxisVector = Value.Get<FVector2D>();
AddControllerYawInput(LookAxisVector.X);
AddControllerPitchInput(LookAxisVector.Y);
}
IA_Look의 값 타입은 FVector2 D(2D 축)이며, Controller의 회전 값을 적절히 설정해 줍니다.
'게임개발 > Unreal C++' 카테고리의 다른 글
[Unreal_Tip]#1_Log 깨짐 현상(한글) (0) | 2024.04.10 |
---|---|
[Unreal]#26_Subsystem, 하위 시스템 (0) | 2024.03.19 |
[Unreal]#26_Game Ability System(GAS) (0) | 2024.02.23 |
[Unreal]#25_Collision Data (1) | 2023.12.02 |
[Unreal]#24_Deactivate와 DeactivateImmediate함수 (0) | 2023.04.16 |