UE5/Lyra

Lyra Input System - Enhanced Input System

게임 개발 2024. 8. 15. 19:54

 

Lyra 프로젝트를 이용한 해당 프로젝트에서의 인풋 시스템을 제작하기에 주요하게 봐야할 내용은

키보드용 파일 하나와 게임 패드용 파일 하나,

총 두개의 파일이 있음을 주목해야합니다.

 

일반적인 입력 동작은 플레이어 이동, 점프와 같은 입력 매핑 컨텍스트를 사용하여 구성됩니다.

 

무기 발사, 무기 재장전, 웅크리기 등등

슈팅 게임 핵심 기능 플러그인에는 키보드용을 포함한 두 개의 다른 확장 파일이 있습니다.

다른 하나는 게임 패드용으로,

추가 입력 동작은 근접 공격, 던지기와 같은 입력 매핑 컨텍스트를 사용하여 구성됩니다.

 

Enhanced Input System

 

Enhanced Input System이 향상된 입력 시스템이라고 불리는 이유는 다음과 같습니다.

이전 입력 시스템(Action/Axis mapping)은 꽤나 획일적이었고,

대규모 프로젝트의 경우

빠른 속도로 다루기  (= 빠른 속도로 프로젝트를 진행시키기 ) 힘들었을 것입니다.

아날로그 스틱에 대한 기본으로 내장된 데드 존(dead zone) 지원이 없었으며,

이를 리팩토링하기 어려웠습니다.

 

++ Plus ++

데드 존 (dead zone)이란,

아날로그 스틱에서 작은 움직임이 감지되지 않도록 설정하는 영역을 의미합니다.

 

하지만 기본적으로 제공되는 기능(= 옛날 입력 시스템은) 이러한 데드존 설정이 없었고,

이를 추가하거나 수정하려면 코드의 많은 부분을 손봐야 했기 떄문에 리팩토링 작업이 어려웠습니다.

+++++++++

 

또한 플레이어의 현재 상태를 고려할 때 플레이어에 대한 컨텍스트 키 매핑을

사용할 수 있는 내장된 방법은 없었습니다.

 

 

동적 및 상황별 입력 매핑(Dynamic and Contextual input mappings)

 

향상된 입력을 사용하면 플레이어의 런타임에 "매핑 컨텍스트"를 추가하고 제거할 수 있으므로

많은 수의 "동작"을 훨씬 더 쉽게 관리할 수 있습니다.

이를 통해 플레이어의 현재 상태에 따라 특정 입력이 어떻게 동작하는지 매우 쉽게 변경할 수 있습니다.

예를 들어, 걷고, 달리고, 엎드릴 수 있는 플레이어가 있는 경우 각 캐릭터 이동 유형에 대해 "매핑 컨텍스트"를 바꿔

CTRL 키가 다른 작업을 수행하도록 할 수 있습니다.

걷고 CTRL을 누르고 있는 동안 웅크리고 있어야 합니다.

달리고 있는 동안 CTRL을 누르고 있는 동안은 미끄러져야합니다.

엎드리고 있는 동안 CTRL을 누르고 있는 동안 다시 일어나야 합니다.

 

 

플러그인 친화적(Plugin-Friendly)

 

향상된 입력은 상당히 플러그인 친화적이고

입력 매핑은 게임 플레이 플러그인을 통해 매우 간단하게 추가가 가능합니다.

즉, 플러그인 내의 모든 입력 로직을 캡슐화하고 동적으로 껐다가 켤 수 있습니다.

예를 들어, 게임에 "차량"의 게임플레이 기능을 추가하는 경우입니다.

"차량X"에 대한 게임플레이 기능 플러그인을 만들고

해당 플러그인 내에 입력 자산을 추가하여 기본 게임 구성 파일을

수정하지 않고도 모든 "차량X" 코드를 하나의 플러그인으로 완전히 캡슐화할 수 있습니다.

 

 

이전 시스템과 호환(Backwards Compatible with the old system)

 

Enhanced Input은 이전 Input "Action and Axis" 매핑과 완벽하게 역호환됩니다.

DefaultPlayerInputClass와 DefaultInputComponentClass를 각각 UEnhancedPlayerInput과

UEnhancedInputComponent에 기반한 것으로 변경하기만 하면 됩니다.

 

 

The Basics(기본 사항)

 

Enhanced Input과 이전 입력 시스템의 가장 큰 차이점 중 하나는 모든 것이 한 곳

(DefaultInput.ini)에서 정의되는 대신 다양한 데이터 자산을 기반으로 작동한다는 것입니다.

이를 통해 입력 로직을 구성하고 게임 기능 플러그인 내에 입력 관련 코드를 캡슐화하여

괸리하기 쉽게 만들 수 있습니다.

 

 

Creating Enhanced Input Assets(향상된 입력 자산 생성)

 

UE 5.1부터 Enhanced Input이 기본적으로 켜져 있습니다.

콘텐츠 브라우저의 "Input" 카테고리에서 입력 자산을 만들 수 있습니다.

 

 

Input Actions(IA) (입력 작업)

 

입력 액션은 "액션" 및 "축" 매핑 이름과 개념적으로 동일하지만 데이터 자산입니다.

각 입력 액션은 "웅크리기" 또는 "무기 발사"와 같이 사용자가 할 수 있는 것을 나타내야 합니다.

이 입력 액션의 상태가 변경될 때 블루프린트나 C++에서 리스너를 추가할 수 있습니다.

 

입력 동작은 동작을 결정하는 여러 가지 다른 "유형"이 될 수 있습니다.

간단한 "부울" 동작이나 더 복잡한 3D 축을 만들 수 있습니다.

동작의 유형은 어떤 값을 얻을 수 있는지 결정합니다.

 

부울 동작은 간단한 부울 값을 갖고,

Axis1D는 float 값이 되고, Axis2D는 FVector2D가 되고,

Axis3D는 전체 FVector가 됩니다.

 

"on" 또는 "off" 상태만 있는 경우 "bool" 액션을 사용해야 합니다.

이는 레거시 입력 시스템의 이전 "Action"매핑과 동일합니다.

게임패드 썸스틱 값과 같은 경우 2D 축 액션을 사용하여

썸스틱 위치의 X 및 Y 값을 보관할 수 있습니다.

3D 축을 사용하여 모션 컨트롤러 정보와 같은 더 복잡한 데이터를 보관할 수 있습니다.

 

 

 

 

Trigger States(트리거 상태)

 

트리거 상태는 시작됨(started), 진행 중(ongoing), 트리거 됨(triggered), 완료됨(completed)과 같이

작업이 있는 현재 상태를 나타냅니다.

대부분의 경우 "트리거 됨" 상태를 원합니다.

C++ 및 Blueprint 모두에서 특정 상태에 바인딩할 수 있습니다.

 

  • Triggered
    액션이 트리거 되었음을 말합니다!
    즉, 모든 트리거 요구 사항에 대한 평가를 완료했음을 의미합니다.
    예를 들어, 사용자가 키를 놓을 때 "누르기 및 해제" 트리거가 전송됩니다.

  • Started
    트리거 평가를 시작한 이벤트가 발생했음을 뜻합니다.
    예를 들어 "Double tap" 트리거를 처음 누르면 "Started" 상태가 한 번 호출됩니다.

  • Ongoing
    트리거가 아직 처리중임을 말합니다.
    예를 들어, 사용자가 지정된 기간에 도달하기 전에 버튼을 누르고 있는 동안
    "누르고 보류" 동작이 진행 중일 때를 뜻합니다.
    트리거에 따라,
    이 이벤트는 입력 값을 받으면 작업이 평가되는 모든 틱을 발생시킵니다.

  • Completed
    트리거 평가 프로세스가 완료되는 것을 뜻합니다.

  • Canceled
    트리거가 취소되었음을 뜻합니다.
    예를 들어, 사용자가 버튼을 누르기 전에
    "누르기를 보류함" 이라는 액션이 트리거 되었을 때를 뜻합니다.

 

Adding Input Listeners(입력 리스너 추가)

 

Bluepints (블루프린트에서 용법)

 

블루프린트에서의 입력 리스너를 추가하는 방법은

블루프린트의 이벤트 그래프를 마우스 오른족 버튼으로 클릭하고

입력 작업 데이터 자산의 이름을 입력할 수 있습니다.

 

 

 

Quick Tip : Input Action 이벤트 노드를 두 번 클릭하여

해당 asset으로 직접 이동할 수 있습니다! C++의 입력 작업에 바인딩할 수도 있습니다.

 

 

C++의 입력 작업에 바인딩할 수도 있습니다 :

// Add Input Listeners on an Actor "AFooBar"
void AFooBar::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    UEnhancedInputComponent* Input = Cast<UEnhancedInputComponent>(PlayerInputComponent);
    // You can bind to any of the trigger events here by changing the "ETriggerEvent" enum value
    Input->BindAction(AimingInputAction, ETriggerEvent::Triggered, this, &AFooBar::SomeCallbackFunc);
}
 
void AFooBar::SomeCallbackFunc(const FInputActionInstance& Instance)
{
    // Get the value of the Input Action for whatever type you want here...
    FVector VectorValue = Instance.GetValue().Get<FVector>();
    FVector2D 2DAxisValue = Instance.GetValue().Get<FVector2D>();
    float FloatValue = Instance.GetValue().Get<float>(); 
    bool BoolValue = Instance.GetValue().Get<bool>();
 
    // Do your cool stuff here!
}

 

 

Input Mapping Contexts (IMC) (입력 매핑 컨텍스트)

 

매핑 컨텍스트는 플러이어가 있을 수 있는 특정 컨텍스트를 나타내는 입력 동작의 컬렉션입니다.

주어진 입력 동작을 트리거하는 데 필요한 규칙을 설명합니다.

여기서 실제 입력 작업 바인딩을 수행하고 각 작업에 대한 추가 트리거 또는 수정자를 지정합니다.

향상된 입력 하위 시스템에 IMC를 추가할 때 우선 순위를 부여할 수도 있습니다.

 

동일한 입력 작업에 매핑된 여러 컨텍스트가 있는 경우 

우선 순위가 높은 컨텍스트는 고려되고 다른 컨텍스트는 무시됩니다.

작업을 거의 하지 않고 입력 코드의 동작을 변경하는 데 좋습니다.

 

입력을 처리하려면 향상된 입력 로컬 플레이어 하위 시스템에 입력 매핑 컨텍스트를 추가해야 합니다.

 

 

 

Mapping Contexts는 Enhanced Input 서브시스템에서 동적으로 추가 및 제거할 수 있으므로

플레이어 시나리오에 따라 다른 컨텍스트를 만들어야 합니다.

예를 들어, 일반적인 "Aiming"입력 매핑 컨텍스트를 가진 다음

"Aiming Down Sights"에 대해 동일한 입력 작업이 매핑되는 두 번째 컨텍스트를 가질 수 있지만

이제는 조준 속도를 늦추기 위한 수식어가 있습니다.

 

Blueprint 또는 C++에서 매핑 컨텍스트를 플레이어에 추가할 수 있습니다.

 

c++에서 로컬 플레이어 매핑 컨텍스트 추가

// Expose a mapping context as a property in your header file...
UPROPERTY(EditAnywhere, Category="Input")
TSoftObjectPtr<UInputMappingContext> InputMapping;
 
 
// In your cpp...
if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player))
{
    if (UEnhancedInputLocalPlayerSubsystem* InputSystem = LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
    {
        if (!InputMapping.IsNull())
        {
            InputSystem->AddMappingContext(InputMapping.LoadSynchronous(), Priority);
        }
    }
}

 

 

 

Input Modifiers(입력 수정자)

 

수정자를 사용하면 사용자의 원시 입력을 변경하고 원하는 대로 조작할 수 있습니다.

예를 들어 아날로그 스틱 입력에 데드 존을 적용하는 것과 같습니다.

이는 입력 트리거가 처리되기 전에 발생합니다.

 

이는 민감도 설정 적용, 여러 프레임에 걸쳐 입력을 부드럽게 처리, 플레이어의 상태에 따라

입력이 작동하는 방식 변경과 같은 작업을 수행하는 데 적합합니다.

 

자체 수정자를 만들 때 UPlayerInput에 액세스할 수 있으므로 소유한 플레이어 컨트롤러에

액세서하여 해당에서 원하는 게임 상태를 가져올 수 있습니다.

 

UInputModifier의 하위 클래스를 생성하고,

"ModifyRaw_Implementation" 함수를 재정의하여 C++ 또는

블루프린트에서 사용자 고유의 입력 수정자를 만들 수 있습니다.

 

 

Example Input Modifier that inverts the look axis if a setting is true

// LyraInputModifiers.h....
 
/** Applies an inversion of axis values based on a setting in the Lyra Shared game settings */
UCLASS(NotBlueprintable, MinimalAPI, meta = (DisplayName = "Lyra Aim Inversion Setting"))
class ULyraInputModifierAimInversion : public UInputModifier
{
    GENERATED_BODY()
     
protected:
    virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override
{
{
    ULyraLocalPlayer* LocalPlayer = LyraInputModifiersHelpers::GetLocalPlayer(PlayerInput);
    if (!LocalPlayer)
    {
        return CurrentValue;
    }
     
    ULyraSettingsShared* Settings = LocalPlayer->GetSharedSettings();
    ensure(Settings);
 
    FVector NewValue = CurrentValue.Get<FVector>();
     
    if (Settings->GetInvertVerticalAxis())
    {
        NewValue.Y *= -1.0f;
    }
     
    if (Settings->GetInvertHorizontalAxis())
    {
        NewValue.X *= -1.0f;
    }
     
    return NewValue;
}
}
};

 

 

Triggers(트리거)

 

입력 트리거는 사용자 입력이 입력 수정자의 선택적 목록을 통과한 후

해당 입력 매핑 컨텍스트 내에서 해당 입력 동작을 활성화해야 하는지 여부를 결정합니다.

 

대부분 입력 트리거는 입력 자체를 분석하여 최소 작동 값을 확인하고

short taps, prolonged holds, 또는 일반적인 "press" or "release" 이벤트와 같은

패턴을 검증합니다.

 

Player Mappable Keys(플레이어 매핑 가능 키)

 

많은 게임은 플레이어가 원하는 것이 키를 다시 매핑할 수 있드록 하고 싶어 합니다.

Enhanced Input은 바로 이 기능을 지원합니다.

이 항목에 대한 자세한 내용은 이 튜토리얼을 확인하세요.

 

 

출저 - 언리얼 라일라프로젝트 설명 공식문서