Unreal

10. The Pawn Class & Enhanced Input System (2)

Kelvin의 게임개발 2024. 1. 3. 12:32
728x90
반응형

1. Enhanced Input System

 

우선 새롭게 InputAction과 InputMappingContext를 만들어준다

 

InputMappingContext를 이용하여 InputAction을 연결해준다

IA_Move라는 InputAction을 W키로 Mapping시킴

 

이제 PlayerController의 EnhanceInputLocalPlayerSubSystem에서 만든 InputMappingContext를 Add해주어야 사용이 가능하다

 

 

만든 InputAction을 Event로 사용할 수 있다

 

이를 C++로 변환하면 아래와 같다

 

InputMappingContext는 UInputMappingContext타입이다

//Bird.h
class UInputMappingContext //전방선언

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Input) //BP에서 직접 IMC를 넣고 Get해서 사용하기 위한 UPROPEPRTY매크로 지정자
UInputMappingContext* BirdMappingContext; //IMC를 담기 위한 변수

 

void ABird::BeginPlay()
{
	Super::BeginPlay();
	
	APlayerController* PlayerController = Cast<APlayerController>(GetController());

	if (PlayerController) //nullptr check
	{
		UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
		
		if (Subsystem) //nullptr check
		{
			Subsystem->AddMappingContext(BirdMappingContext, 0);
		}
	}
}

GetController() : 해당 Pawn의 Controller를 AController*로 반환한다

 

Cast<>() : Cast<원하는 타입>(변수);로 변수를 원하는 타입으로 Cast할 수 있다 (Cast<>후 항상 캐스팅이 잘 되었는지 nullptr체크가 필요하다)

 

CastChecked<>() : Cast와 같은 방식으로 사용한다 하지만 Cast실패시 Crash 발생시킴

 

EnhanceInputLocalPlayerSubsystem은 UnhanceInputLocalPlayerSubsystem*타입이다

 

이때 EnhanceInputLocalPlayerSubsystem을 사용하기 위해서는 Module추가 / 헤더 추가가 필요하다

 

 

Module은 자신의 프로젝트명.Build.cs파일에서 추가가 가능하다

 

PublicDependencyModuleNames.AddRange에 "EnhancedInput"을 추가해주면 된다

 

이때 Module추가 후 계속해서 빨간줄이 생긴다면 Project Folder에서 Saved, Intermediate, Binaries 파일들을 제거 후 uproject파일 우클릭 -> Generate Visual Studio Project File로 Generate해주면 된다

 

 

ULocalPlayer::GetSubsystem<>() : Template함수로서 SubsystemClass*를 반환한다

 

LocalPlayer (ULocalPlayer*)를 인자로 받고 <>에는 원하는 SubsystemType을 넣어주면 된다

 

AddMappingContext() : EnhancedInputLocalPlayerSubsystem에서 InputMappingContext를 Add해준다

 

InputMappingContext (UInputMappingContext*), Priority (int32), Options (FModifyContextOptions&)를 인자로 가진다

 

이후에 BP에서 C++에서 만든 UInputMappintContext*를 넣어주면 된다

 

 

이제 InputAction Event를 사용해야 하기 위한 프로그래밍이 필요하다

 

InputAction은 UInputAction*타입이다

class UInputAction;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Input)
UInputAction* MoveAction;

 

InputAction에 Bind할 함수도 제작해야 한다

#include "InputActionValue.h" //헤더추가 필요

void Move(const FInputActionValue& Value);

 

이때 기존의 AxisBind와 EnhancedInputSystem의 차이점이 나타난다 바로 Bind할 콜백함수의 매개변수로 float 변수가 아닌 const FInputActionValue& 타입 변수가 들어가야 한다는 것이다

(InputAction의 Value가 bool, 1D, 2D로 여러개가 들어갈 수 있기 때문이다)

 

void ABird::Move(const FInputActionValue& Value)
{
	const bool CurrentValue = Value.Get<bool>();
}

 

Get<>() : Template함수로 FInputActionValue&타입의 Value를 반환한다

 

<>에는 InputAction에 사용한 Value의 Type을 작성하면 된다

 

 

이제 만든 함수를 InputAction에 Bind시켜야 한다

 

void ABird::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	//PlayerInputComponent->BindAxis(FName("MoveForward"), this, &ABird::MoveForward);
	
	if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
	{
		EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ABird::Move);
	}
}

 

기존에 사용하던 UInputComponent*는 UEnhancedInputComponent*로 Cast후 사용해야 한다

 

BindAction() : 원하는 함수를 원하는 InputAction에 TriggerEvent를 Setting하여 Bind해준다

 

InputAction (UInputAction*), Completed / Triggered / On Going 등등 (ETriggerEvent), this (UObject*), 클래스 이름으로 정규화 된 함수주소를 인자로 가진다

 

 

Pawn을 움직이기 위해서는 1D float Value가 필요하다 따라서 InputAction의 Value를 1D float으로 변경해야 한다

W키를 누르면 1 안누르면 0을 반환한다

 

W키를 누르면 양수 S키를 누르면 음수가 나오게 하기 위해서

 

IMC에서 W S키를 각각 추가해주고 S는 Modifier Negate를 추가하여 반대로 반환하게 해야한다

 

이제 실질적으로 움직이게 하는 함수를 작성한다

void ABird::Move(const FInputActionValue& Value)
{
	const float DirectionValue = Value.Get<float>();

	if (Controller && DirectionValue != 0.f)
	{
		FVector ForwardVector = GetActorForwardVector();

		AddMovementInput(ForwardVector, DirectionValue);
	}
}

GetActorForwardVector() : Actor의 전방벡터를 FVector로 반환한다

 

AddMovementInput() : Pawn을 원하는 방향에 원하는 Value만큼 이동시킨다 (Floating Pawn Movement 컴포넌트가 반드시 존재해야 한다)

 

방향벡터 (FVector), Value (float)을 인자로 가진다

 

 

InputAction에 해당 함수를 Bind해주면 W,S키로 Possessed된 Pawn을 앞 뒤로 움직일 수 있다

728x90
반응형