필요한 개념
플레이어는 BP와 마찬가지로 ACharacter로 부터 상속받아 구현한다.
CPlayer 클래스 생성(ACharacter 상속받는)
Tip) C를 접두사로 붙이는 이유는 -> unreal에 있는 클래스와 구분하기 위해
기본적인 #include 헤더 설명
#include "CoreMinimal.h"
#include "GameFramework/Character.h" -> 여기에는 자기가 상속받을 클래스가 나온다.
#include "CPlayer.generated.h" -> GENERATED_BODY()에 대한 헤더를 가짐(UCLASS()가 붙을때만 나옴)
UCLASS() -> 즉, 언리얼에서 사용할 클래스 임을 명시
class UONLINE_03_CPP_API ACPlayer : public ACharacter
{
GENERATED_BODY() -> 블루프린트에 들어갈려면 어떤 코드가 필요한데, 그 코드들을 대체해주는 매크로
}
CoreMinimal.h : 언리얼에서 필수적으로 사용될 클래스들이 모여있는 헤더(ex) 수학 클래스 같은 기본적 클래스)
generated.h, UCLASS(), GENERATED_BODY() 모두 하나의 쌍
UCLASS()는 BP에서도 이 클래스를 사용할 수 있다는 의미(통신상의 의미), 얘를 기반으로 BP생성가능한 이유가 이 키워드 때문
UCLASS()에 ALT + E해서 보면 Blueprintable(블루프린트 이벤트등 얘로 블루프린트화 할 수있다는것), BlueprintType(블루프린트 타입으로 다룰 수 있다.)
이 두개 체크시에 블루프린트 자체로 다룰 수 있다.(상속 안받고도) 잘 안씀...
UCLASS()
class UONLINE_03_CPP_API ACPlayer : public ACharacter
{
이 부분
GENERATED_BODY()
1. class와 GENERATED_BODY() 사이에는 어떠한 코드도 들어가면 안된다.
why? 사이에 코드가 들어가면 GENERATED_BODY() 매크로랑 코드가 섞인다.
#include ""
이 부분
UCLASS()
class UONLINE_03_CPP_API ACPlayer : public ACharacter
2. 헤더와 class선언 위에 부분에는 무언가 들어갈 수 있지만, 델리게이션 부분, 구조체 선언 밖에 거의 안들어감
기본적으로 ACharacter를 상속받아 cpp를 생성하면
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;가 들어가 있다.
SetupPlayerInputComponent : 플레이어의 입력을 받아 우리가 원하는대로 처리할 수 있도록 하는 함수
(ex) PlayerController가 있다면 이 함수를 무시한다, 우리는 현재 Controller를 쓰지 않아서 이 함수를 통해 입력을 받아올 것임)
항상 프로그램팀은 기본값을 하나 설정해주고 필요시 다른 팀에서 다른 값으로 변경해서 쓰도록 해준다.
(ex) 캐릭터를 하나를 넣어놓고 디자인팀에서 알아서 세팅함)
* CPlayer.cpp 참고 이미지


CPlayer.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "CPlayer.generated.h"
UCLASS()
class UONLINE_03_CPP_API ACPlayer : public ACharacter
{
GENERATED_BODY()
private:
// 비추는 카메라랑 간격을 설정하기 위해 SpringArm 필요
UPROPERTY(VisibleDefaultsOnly)
class USpringArmComponent* SpringArm;
// 카메라를 담당하는 컴포넌트
UPROPERTY(VisibleDefaultsOnly)
class UCameraComponent* Camera;
public:
ACPlayer();
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
CPlayer.cpp
#include "CPlayer.h"
#include "Global.h"
#include "GameFramework/SpringArmComponent.h" // SpringArm 컴포넌트의 위치
#include "GameFramework/CharacterMovementComponent.h" // CharacterMovement컴포넌트 사용을 위한
#include "Camera/CameraComponent.h" // 카메라 컴포넌트의 위치
#include "Components/CapsuleComponent.h" // 캡슐컴포넌트의 위치
ACPlayer::ACPlayer()
{
PrimaryActorTick.bCanEverTick = true;
// CreateDefaultSubobject() : 컴포넌트 만들때 항상 이 함수 씀
// 이전에는 mesh에 붙여주었지만, 지금은 CapsuleComponent에 붙임
// 나중에 건슈팅 모드할때 더 편하다.
// 캐릭터의 기본은 CapsuleComponent가 있다.
//SpringArm = CreateDefaultSubobject<USpringArmComponent>("SpringArm");
//SpringArm->SetupAttachment(GetCapsuleComponent());
//
//Camera = CreateDefaultSubobject<UCameraComponent>("Camera");
//// 스프링암에 카메라를 붙여 넣음
//Camera->SetupAttachment(SpringArm);
// Capsule 컴포넌트에 붙일 것임
CHelpers::CreateComponent<USpringArmComponent>(this, &SpringArm, "SpringArm", GetCapsuleComponent());
// 스프링암에 카메라를 붙여 넣음
CHelpers::CreateComponent<UCameraComponent>(this, &Camera, "Camera", SpringArm);
// bUseControllerRotationYaw
// 이 코드는 캐릭터가 카메라의 회전을 따라서 회전하지 않도록 한다.
bUseControllerRotationYaw = false;
// 이동하는 방향으로 회전
GetCharacterMovement()->bOrientRotationToMovement = true;
GetCharacterMovement()->MaxWalkSpeed = 400.0f; // 기본 속도
// 에셋 가져오고
USkeletalMesh* mesh;
CHelpers::GetAsset<USkeletalMesh>(&mesh, "SkeletalMesh'/Game/Character/Mesh/SK_Mannequin.SK_Mannequin'");
// SkeletalMesh 세팅
GetMesh()->SetSkeletalMesh(mesh);
// SkeletalMesh의 위치와 회전을 기본값으로 넣어주기 위해
// 생성자에 값을 설정해준다.
// SetRelativeLocation : 상대위치 세팅
// SetRelativeLocation : 상대위치 세팅
GetMesh()->SetRelativeLocation(FVector(0, 0, -90));
// 우리는 Yaw(수직회전)해야 하기 때문에, Yaw(가운데) 세팅
// BP상에서 회전 x,y,z는 Roll, Pitch, Yaw 다.
// C에서랑 혼동주의
GetMesh()->SetRelativeRotation(FRotator(0, -90, 0));
}
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
Helpers.h 추가된 내용
class UONLINE_03_CPP_API CHelpers
{
...
public:
// 1 : 어느 액터에 붙을 컴포넌트냐? 2 : 생성해서 붙여서 리턴할 컴포넌트, 3: 변수명, 4 : Actor컴포넌트가 최상위 컴포넌트 인데, Transform이 추가된 것(부모,자식 관계를 갖는애)이 SceneComponent이다. NULL이면 루트로감
template<typename T>
static void CreateComponent(AActor* InActor, T** InComponent, FName InName, USceneComponent* InParent = NULL)
{
*InComponent = InActor->CreateDefaultSubobject<T>(InName);
// Parent가 NULL이 아니라면
if (!!InParent)
{
(*InComponent)->SetupAttachment(InParent);
return;
}
// NULL이라면 부모가 없는것이다.
// 부모가 없다면 InComponent가 루트가 됨
InActor->SetRootComponent((*InComponent));
}
}
결과

'Unreal Engine 4 > C++' 카테고리의 다른 글
| <Unreal C++> 10 - UAnimInstance (0) | 2022.04.07 |
|---|---|
| <Unreal C++> 9 - PlayerInputComponent (0) | 2022.04.04 |
| <Unreal C++> 7 - Material (0) | 2022.04.04 |
| <Unreal C++> 4 - Actor Spawn (0) | 2022.04.04 |
| <Unreal C++> 2 - C++과 BP 통신 (0) | 2022.03.30 |