본문 바로가기
Engine/Unreal

언리얼 Enhanced Input System

by 뇌 속의 통 2025. 7. 17.

Enhanced Input System이란?

말 그대로 향상된 입력 시스템을 뜻한다.

 

게임을 만들때 키보드를 이용해서 진행하도록 만드는 경우, 사용자가 게임 패드를 사용하는 경우 등 입력 장치들이 다양해짐에 따라 훨씬 쉽게 간단하게 입력을 받을 수 있도록 하기 위해 만들어진 시스템이다.

 

점프 기능을 만들고 그 기능에 스페이스바, 게임패트의 X버튼 등 연동만 하면 알아서 유저가 사용하는 입력 장치에 따라 동일하게 동작할 수 있게 해준다.

 

이를 이용하여 캐릭터의 움직임을 구현해보면 아래와 같다.

(참고로 언리얼의 C++ 프로젝트 기준으로 작성하였음)

우선 언리얼 내에서 Enhanced Input 플러그인을 활성화 시켜준다.

 

언리얼 프로젝트 폴더 내 bulid.cs 파일을 열어 ModuleNames.AddRange() 함수의 매개변수로 EnhancedInput 을 추가해주도록 한다.

 

 

bulid.cs 파일은 외부 모듈 사용 여부, PCH 사용 여부 등 설정하기 위한 파일이다.

여기서 우리가 사용할 모듈을 추가해줘야하는데 그게 바로 AddRange에 string 형태로 넣어주는 것이다.

 

그 다음 InputAction을 하나 새로 만들어준다.

IA(InputAction) : 역할에 대한 정보값을 구성하는 Asset 입력받는 정보를 정하는 것(Vector, bool, float 등).

ex) IA_Jump 는 bool형 true, false 값만 받을 것이다. 해당 된 키를 누르면 true, 누르지 않는다면 false

 

그 다음 IMC(Input Mapping Context)를 만들어준 뒤 IA에 어떤 키를 눌러야 정보 값을 넘겨줄지 설정한다.

 

**IMC란?

모든 IA를 관리하는 기능이다.

모든 Input Action들을 모아 특정 키와 맵핑시키는 역할을 한다.

 

IMC 설정 옵션

Negate : 반대의 값을 넣어준다.(음수)

Swizzle Input Axis Value : 넣어주는 값을 XYZ 순이 아닌 YXZ 처럼 순서를 바꿔준다.

즉, 바꾸지 않으면 X에 데이터를 넣어주는데 Y나 Z로 바꿔줌으로써 특정 축으로 들어오는 값을 분리할 수 있다.

Down : 키를 누르는 동안 계속해서 값이 들어온다.

Pressed : 키를 누르는 순간 값이 들어온다. (한번)

Released : 키를 떼는 순간 값이 들어온다. (한번)

 

원래 Input class로 받았다면 EnhancedInput에서는 InputAction로 값을 받아 Input Context로 넘기는 것이다.

(수치, true 등등)

 

실행중에도 동적으로 바꿀수 있도록 한 것이 바로 EnhancedInput이다.

 

 

 

이제 해당 키로 받아 온 값을 바탕으로 무엇을 할지 기능을 넣어야 하므로 Charater Class를 상속받아 새로운 Class를 만들어준다.

 

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "InputActionValue.h"
#include "MyEnhancedInputCharacter.generated.h"

class UCameraComponent;
class USpringArmComponent;
class UInputAction;

UCLASS()
class L20240625_API AMyEnhancedInputCharacter : public ACharacter
{
	GENERATED_BODY()

public:
	AMyEnhancedInputCharacter();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
	TObjectPtr<UCameraComponent> Camera;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
	TObjectPtr<USpringArmComponent> CameraBoom;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	TObjectPtr<UInputAction> IA_EnhancedMove;


	UFUNCTION()
	void Move(const FInputActionValue& Value);


};

header에서 우리가 사용할 함수, 변수를 선언해주도록 한다.

 

UFUNCTION(), UCLASS(), UPROPERTY()는 언리얼에서 제공해주는 매크로로 기존 C++의 기능을 더욱 확장해준다라고 볼 수이다. 이는 추후에 더 자세히 다루도록 하겠다.

 

또한, 포인터로 클래스를 사용하는 경우 굳이 해당 header를 Include하지 않고 전방선언을 하여 컴파일 시간을 단축해주도록 하자.

(순환 참조 문제도 방지된다.)

 

이제 header에서 선언한 함수를 cpp에서 구현해주도록 한다.

#include "MyEnhancedInputCharacter.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"



AMyEnhancedInputCharacter::AMyEnhancedInputCharacter()
{
	PrimaryActorTick.bCanEverTick = true;

	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(RootComponent);

	Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
	Camera->SetupAttachment(CameraBoom);

}

void AMyEnhancedInputCharacter::BeginPlay()
{
	Super::BeginPlay();
	
}

void AMyEnhancedInputCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}


void AMyEnhancedInputCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	UEnhancedInputComponent* MyEnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent);

	if(MyEnhancedInputComponent)
	{
		MyEnhancedInputComponent->BindAction(IA_EnhancedMove, ETriggerEvent::Triggered, this, &AMyEnhancedInputCharacter::Move);
	}

}

void AMyEnhancedInputCharacter::Move(const FInputActionValue& Value)
{
	FVector2D MyVector = Value.Get<FVector2D>();
	AddMovementInput(GetActorForwardVector() * MyVector.X);
	AddMovementInput(GetActorRightVector() * MyVector.Y);
}

 

사용할때에는 UInputComponent의 자식인 UEnhancedInputComponent로 Cast하여 사용하자.

당연한 소리지만 자식 Class에서 별도로 추가한 함수들을 쓰기 위해선 형변환을 해줘야한다.

 

추가로 Controller도 구현해주도록 한다.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "MyEnhancedInputPlayerController.generated.h"

class UInputMappingContext;

UCLASS()
class L20240625_API AMyEnhancedInputPlayerController : public APlayerController
{
	GENERATED_BODY()
	
public:

	virtual void BeginPlay() override;
	virtual void OnPossess(APawn* aPawn) override;

	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	TObjectPtr<UInputMappingContext> InputMappingContext;
};
#include "MyEnhancedInputPlayerController.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"

void AMyEnhancedInputPlayerController::BeginPlay()
{
	Super::BeginPlay();
}

void AMyEnhancedInputPlayerController::OnPossess(APawn* aPawn)
{
	Super::OnPossess(aPawn);

	if(InputMappingContext)
	{
		ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>
		(GetLocalPlayer())->AddMappingContext(InputMappingContext, 0);

	}
}

 

다 완성되고 나면 해당 C++을 상속받는 BP를 만들어주고, 우리가 만든 IA를 할당해주도록 한다.

 

이제 월드에 해당캐릭터를 배치하고 실행하면 우리가 맵핑한 키를 누르면 해당 동작하는 것을 볼 수 있다.

'Engine > Unreal' 카테고리의 다른 글

Unreal Dedicated Server 설정하기  (4) 2025.07.10
Unreal C++로 Black Jack Game 만들기(+열거형)  (4) 2025.07.09
언리얼의 기초 2  (0) 2025.01.06
언리얼 엔진의 기초  (0) 2024.11.27
언리얼 엔진에 fbx 파일 임포트 하기  (0) 2024.11.22