필요한 개념
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 세팅하면됨
Default Pawn Class변수에 BP_CPlayer가 들어간 것을 볼 수 있다.
움직이지는 않음 -> 디폴트 게임모드가 아니니깐...
* 움직임을 처리하기 위해(키 등록)
엔진 -> 입력
ActionMapping, Axis Mapping 세팅해야 함
다른 프로젝트것을 익스포트 임포트 해서 가져올 수도 있다.'
요약
SetupPlayerInputComponent
-PlayerInputComponent
-BindAxis("축 이름", 객체, 함수주소)
회전
-FRotator
-FQuat
* CPlayer.cpp 참고 이미지
함수 그대로 CPlayer.cpp에 구현
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 |