본문 바로가기

Unreal Engine 4/C++

<Unreal C++> 9 - PlayerInputComponent

 

필요한 개념


BP랑 비슷하지만 다른 면도 있음

콘텐츠 브라우저에서 C++클래스에서 클래스 기존 이름을 바꿀 수 없다. VisualStuio에서 바꿔야함
UOnline_03_CppGameModeBase.h -> CGameMode로 바꿈

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "UOnline_03_CppGameModeBase.generated.h" -> UOnline_03_CppGameModeBase(파일명), 파일명 변경시 이부분도 바꾸면 된다.

UCLASS()
// AUOnline_03_CppGameModeBase : A + 파일명이 붙어 클래스명
class UONLINE_03_CPP_API AUOnline_03_CppGameModeBase : public AGameModeBase -> AGameModeBase도 Actor를 상속 받는다.
{
GENERATED_BODY()
};

그래서 간단히 전체 이름을 바꿀려면 파일명 UOnline_03_CppGameModeBase 부분을 현재 문서까지 바꾸면 된다.

게임모드를 BP로 만들어서 써도 되지만 여기서는 C로 만듬

 

* GameMode 세팅

 

GameMode 세팅


언리얼에서 세팅 -> 프로젝트 세팅 -> 맵&모드->GameMode 세팅하면됨
Default Pawn Class변수에 BP_CPlayer가 들어간 것을 볼 수 있다.

움직이지는 않음 -> 디폴트 게임모드가 아니니깐...

* 움직임을 처리하기 위해(키 등록)

 

입력 키 Mapping 처리


엔진 -> 입력
ActionMapping, Axis Mapping 세팅해야 함
다른 프로젝트것을 익스포트 임포트 해서 가져올 수도 있다.'

요약
SetupPlayerInputComponent
-PlayerInputComponent
-BindAxis("축 이름", 객체, 함수주소)

회전
-FRotator
-FQuat

 

* CPlayer.cpp 참고 이미지

 

함수 그대로 CPlayer.cpp에 구현

 

Move

 

Mouse Rotation

 

 

 

 

CGameMode.h


더보기
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "CGameMode.generated.h"

UCLASS()
class UONLINE_03_CPP_API ACGameMode : public AGameModeBase
{
	GENERATED_BODY()
	
public:
	ACGameMode();
};

 

 

 

 

 

 

 

CGameMode.cpp


더보기
#include "CGameMode.h"
#include "Global.h"

ACGameMode::ACGameMode()
{
	// 플레이어 BP 클래스를 불러와야 한다.
	// DefaultPawnClass : 기본 플레이어 클래스를 입력받을 변수
	// TSubclassOf<APawn> : APawn로부터 상속 받은 하위 클래스의 타입을 입력
	// APawn이하로 타입이 지정될 수 있도록 하는 리플렉션이다.
	// 우리의 BP_Player -> CPlayer를 상속 받고 -> ACharacter-> APawn
	// 그래서 Upcasting이 가능
	// CPlayer class를 가지고 쓴다면 BP기능을 사용 못한다. 그래서
	// 우리가 만든 BP_Player를 가져다 써야 한다.
	// CPlayer는 찾아올 수 있지만, BP_CPlayer는 찾아올 수 없다.
	// 그래서 BP_CPlayer도 에셋이니까, 얘를 불러옴(레퍼런스 복사)
	// Blueprint'/Game/BP_CPlayer.BP_CPlayer'
	
	// 클래스의 타입을 찾아와야 한다. TSubClassOf를 사용하기 위해
	// -> ConstructorHelpers::FClassFinder() : 생성자에서 클래스의 타입을 불러올 수 있는 객체
	// <불를려는 자료형>
	// Blueprint : 블루프린트 클래스 타입
	// 주의할 사항은 블루프린트 클래스 타입을 로딩할 때에는 식별자에 _C를 반드시 붙여줘야 정상적으로 불러진다. 
	//ConstructorHelpers::FClassFinder<APawn> pawn(L"Blueprint'/Game/BP_CPlayer.BP_CPlayer_C'");
	//if(pawn.Succeeded())
	//	pawn.Class = 
	

	// 기본 플레이어	
	CHelpers::GetClass<APawn>(&DefaultPawnClass, "Blueprint'/Game/BP_CPlayer.BP_CPlayer_C'");
}

 

 

CPlayer.h 추가된 내용


더보기
UCLASS()
class UONLINE_03_CPP_API ACPlayer : public ACharacter
{
    GENERATED_BODY()
    
    ...

public:
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

private:
	// MoveFoward 이벤트는 Axis Value(float)이 들어온다.(BP를 보면)
	void OnMoveForward(float Axis);	
	void OnMoveRight(float Axis);
	void OnHorizentalLook(float Axis);
	void OnVerticalLook(float Axis);
}

 

 

 

 

 

 

 

CPlayer.cpp 추가된 내용


더보기
...
ACPlayer::ACPlayer()
{
	...
	SpringArm->SetRelativeLocation(FVector(0, 0, 60));
	// 거리
	SpringArm->TargetArmLength = 200.0f;
	// 벽 같은데 붙어서 선 사이에 물체 들어오면 충돌체크 할거냐?
	// true시 카메라 뒤집어짐
	SpringArm->bDoCollisionTest = false;
	// 컨트롤러에 따라 폰이 회전할거냐?
	SpringArm->bUsePawnControlRotation = true;
}

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

	//BindAxis : 축 값의 이벤트와 함수를 연결(축 매핑)
	// 1 : 축 값의 이벤트 이름 2 : 호출할려는 함수 주소를 가진 객체 3 : 입력했을때 어느 객체에 있는 함수를 콜할거냐
	// 함수 포인터를 사용할때는 함수의 주소로 명시해 주어야 한다.
	PlayerInputComponent->BindAxis("MoveForward", this, &ACPlayer::OnMoveForward);
	PlayerInputComponent->BindAxis("MoveRight", this, &ACPlayer::OnMoveRight);
	PlayerInputComponent->BindAxis("HorizontalLook", this, &ACPlayer::OnHorizentalLook);
	PlayerInputComponent->BindAxis("VerticalLook", this, &ACPlayer::OnVerticalLook);
}

void ACPlayer::OnMoveForward(float Axis)
{
	// 오일러각
	FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
	// FRotator는 BP와 다르게 GetForwardVector()가 없다.
	// 모든 게임엔진에는 쿼터니언(사원수)를 씀(회전 오차 없앰, 짐벌락 방지)
	// 사원수 : 회전의 연산이 회전행렬(FMatrix)에 비해 간단하며 값 오차를 최재한 줄이기 위해 회전에서 사용되는 방식
	// FRotator에 없는 함수를 사용하기 위해 사용함
	// Rotator와 쿼터니언은 항상 1대1로 매핑이됨(서로 변환이 됨)
	// Rotator에 함수가 없다면 쿼터니언으로 변환하고 해보면 있을 것임
	FVector direction = FQuat(rotator).GetForwardVector().GetSafeNormal2D();

	AddMovementInput(direction, Axis);
}

void ACPlayer::OnMoveRight(float Axis)
{
	FRotator rotator = FRotator(0, GetControlRotation().Yaw, 0);
	FVector direction = FQuat(rotator).GetRightVector().GetSafeNormal2D();

	AddMovementInput(direction, Axis);
}

void ACPlayer::OnHorizentalLook(float Axis)
{
	// Yaw는 좌 ~ 우
	AddControllerYawInput(Axis);
}

void ACPlayer::OnVerticalLook(float Axis)
{
	// Pitch는 위 아래
	AddControllerPitchInput(Axis);
}

 

 

 

 

 

CHelpers.h 추가된 내용


더보기
class UONLINE_03_CPP_API CHelpers
{
public:
	...
	// TSubclassOf는 기본적으로 *를 가지고 있음
	// 그래서 밑에 변수는 2차 포인터가 됨
	template<typename T>
	static void GetClass(TSubclassOf<T>* OutClass, FString InPath)
	{
		ConstructorHelpers::FClassFinder<T> asset(*InPath);
		verifyf(asset.Succeeded(), L"asset.Succeeded()");

		*OutClass = asset.Class;
	}
}

 

 

 

결과


키보드 입력 및 마우스 입력이 잘 되는 것을 볼 수 있다.

Yaw를 통해 GetFowardVector(), GetRightVector()를 통해 키보드 이동키를 처리하고 있고,

마우스는 Yaw(Horizontal), Pitch(Vertical)을 통해 회전을 표현하고 있다.

 

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

<Unreal C++> 11 - Debug(출력로그, 게임창)  (0) 2022.04.07
<Unreal C++> 10 - UAnimInstance  (0) 2022.04.07
<Unreal C++> 8 - Player  (0) 2022.04.04
<Unreal C++> 7 - Material  (0) 2022.04.04
<Unreal C++> 4 - Actor Spawn  (0) 2022.04.04