2024. 8. 2. 02:39ㆍUnreal Engine
C++ 주의할 점
class SHOOTING_API ACPlayer : public APawn
콜론은 상속을 의미한다. A가 앞에 붙는 이유는 Actor이기 때문.
최상단 상속은 UObject이다.
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
"CPlayer.generated.h"는 항상 맨 아래에 있어야 한다. 순서를 바꾸면 에러가 발생한다.
BP_Player 하위의 Cube로 붙어있는 StaticMesh Component를 CPlayer C++에서 붙여본다.
CPlayer.h 헤더파일에서, 코드를 추가한다.
public:
class UStaticMeshComponent* BodyMesh;
*은 포인터이다. UStaticMeshComponent는 자료형, BodyMesh는 그릇
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
UCLASS()
class SHOOTING_API ACPlayer : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACPlayer();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
public:
class UStaticMeshComponent* BodyMesh;
};
CPlayer.cpp에서는, BodyMesh 이하의 코드줄을 추가한다.
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
}
디폴트의 하위라서 서브 오브젝트를 만들어준다는 CreateDefaultSubobject를 사용. <> 안에는 만들고 싶은 컴포넌트 타입 자료형을 넣으면 된다. 저 위에 캡쳐사진에서 Cube 자리가 "BodyMesh"가 된다는 말이다.
Ctrl + B 눌러서 빌드.
잘 되었다면 다시 에디터로 돌아와서 Viewport에 Pawn을 올려놓았을 때 "BodyMesh" 이름의 하위 오브젝트가 생성된 것을 볼 수 있다.
이렇게 바로 쓰지 않고 Blueprint로 바꿔서 사용한다.
Pawn에 우클릭 후 [Create Blueprint class based on CPlayer] 선택.
"BP_CPlayer" 이름으로 생성.
우측 Details 창에는 아무것도 나오지 않는다.
Details가 나오게 하기
헤더파일에서, URPOPERTY 부분을 추가한다.
VisibleAnywhere는 Class와 Instance 둘 다 특정 컴포넌트를 볼 수 있게 한다. 값 변경 불가능.
VisibleDefaultsOnly, VisibleInstanceOnly는 각각 Class, Instance 에서만 볼 수 있게 한다.
EditAnywhere은 값도 바꿀 수 있다.
public:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
UCLASS()
class SHOOTING_API ACPlayer : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACPlayer();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
public:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
};
빌드가 잘 되었다면 [Details] 부분이 나오는 것을 볼 수 있다.
VisibleAnywhere 뒤에 BluprintReadOnly라고 추가로 붙이면, 드래그 앤 드랍으로 블루프린트에 가져와도 오직 Get으로만 가져올 수 있다. (BlueprintReadWrite 하면 Get Set 가능)
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
class UStaticMeshComponent* BodyMesh;
};
참고로, 블루프린트에서 [Show Inherited Variables]를 활성화하면 부모의 Variables도 가져올 수 있다.
이제 블루프린트로만 만들었던 Cube 이하의 서브 오브젝트를 C++에서 만들어본다.
헤더파일에서 코드를 추가한다.
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* SpaceShipMesh;
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "CPlayer.generated.h"
UCLASS()
class SHOOTING_API ACPlayer : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ACPlayer();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
public:
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* BodyMesh;
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* SpaceShipMesh;
};
C++ 파일에서도 코드 추가
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
int32 number1 = 205;
int32 number2 = 5;
UE_LOG(LogTemp, Warning, TEXT("%d"), number1 + number2);
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
Ctrl + B로 빌드
에디터로 돌아가면 SpaceShipMesh가 생성되어 있는 것을 볼 수 있다.
BodyMesh를 루트 컴포넌트로 등록하고, SpaceShipMesh는 자식 컴포넌트로 변경
C++ 코드 추가
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh->SetupAttachment(BodyMesh);
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
SpaceShipMesh->SetupAttachment(BodyMesh);
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
에디터로 돌아가면 BodyMesh가 루트 컴포넌트가 되어있는 것을 볼 수 있다.
동적으로 SpaceShipMesh에 모델링 넣기
C++ 코드 추가
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Game/SpaceShip/Spaceship_ARA.Spaceship_ARA'"));
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
}
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
SpaceShipMesh->SetupAttachment(BodyMesh);
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Game/SpaceShip/Spaceship_ARA.Spaceship_ARA'"));
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
}
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
우측 Static Mesh에 모델링이 들어와 있는 것을 볼 수 있다.
위치 값 세팅하기
C++ 코드 추가
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
//부모 기준 상대적 위치값 세팅. 회전 순서는 Y, Z, X 순서임
SpaceShipMesh->SetRelativeRotation(FRotator(0, 90, 90));
//크기 세팅
SpaceShipMesh->SetRelativeScale3D(FVector(6));
}
회전 값은 Copy해서 코드에 붙여넣는다.
전체 코드
// Fill out your copyright notice in the Description page of Project Settings.
#include "CPlayer.h"
// Sets default values
ACPlayer::ACPlayer()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
//BodyMesh 그릇에 StaticMeshComponent를 만들어서 담으려고 한다.
BodyMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BodyMesh"));
//BodyMesh를 Root로 등록
RootComponent = BodyMesh;
SpaceShipMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("SpaceShipMesh"));
SpaceShipMesh->SetupAttachment(BodyMesh);
//사용할 Static Mesh 데이터를 읽어서 컴포넌트에 할당하기
ConstructorHelpers::FObjectFinder<UStaticMesh> TempMesh(TEXT("/Script/Engine.StaticMesh'/Game/SpaceShip/Spaceship_ARA.Spaceship_ARA'"));
//로딩 성공하면 SpaceShipMesh에 사용할 Static Mesh로 TempMesh를 넣는다.
if (TempMesh.Succeeded())
{
SpaceShipMesh->SetStaticMesh(TempMesh.Object);
//부모 기준 상대적 위치값 세팅. 회전 순서는 Y, Z, X 순서임
SpaceShipMesh->SetRelativeRotation(FRotator(0, 90, 90));
//크기 세팅
SpaceShipMesh->SetRelativeScale3D(FVector(6));
}
}
// Called when the game starts or when spawned
void ACPlayer::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
회전과 스케일 값이 잘 들어온 것을 볼 수 있다.
'Unreal Engine' 카테고리의 다른 글
[Unreal] 16일차 - C++ 적 생성, 콜라이더 설정, 적 이동, 적이 타겟으로 회전, 충돌 처리 (0) | 2024.08.03 |
---|---|
[Unreal] 15일차 - C++ 플레이어 이동, 총알 생성 및 발사하기 (0) | 2024.08.03 |
[Unreal] 13일차 - C++ 시작, Hello World 출력, 자료형 (0) | 2024.08.01 |
[Unreal] 12일차 - 적 모델링 교체, 적끼리 충돌 방지, 트리거 박스, 적이 나를 보면서 오도록 수정, 사운드 추가, 폭발 이펙트, 배경 스크롤 (0) | 2024.07.30 |
[Unreal] 11일차 - 일정시간에 한 번씩 적 만들기, 적이 플레이어 따라오게 설정, 초반 방향만 따라오게 설정, 확률 추가, 플레이어 모델링 교체 (0) | 2024.07.28 |