Unreal

8. The Pawn Class (1)

Kelvin의 게임개발 2023. 12. 15. 00:58
728x90
반응형

1. The Pawn Class

 

Pawn은 Controller가 Possess할 수 있다 (직접 컨트롤 할 수 있다)
ex) 마우스, 키보드 클릭으로 Pawn을 제어할 수 있다

 

Pawn Class는 Actor Class를 상속받는다


Pawn Class를 만들기 위해서는 APawn을 상속받아 클래스 생성을 해주면 된다

 

생성하게 되면 APawn을 상속받은 클래스가 만들어진다

UCLASS()
class STUDYUE_API ABird : public APawn //APawn 상속
{
	GENERATED_BODY()

public:
	ABird();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

	//키보드, 마우스 등의 입력을 받는 함수이다
    	//APawn의 함수를 override해서 사용한다
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

};

 

 

2. Capsule Component

 

Mesh들은 수많은 Poligon으로 구성되어 있다

충돌 체크를 할 때 이 Mesh Poligon으로 충돌 체크를 하면 많은 연산이 필요하게 된다

그렇기 때문에 충돌 체크를 할 때는 조금 더 단순한 모양의 Collision으로 체크한다

 

이럴때 사용하는게 바로 CapsuleComponent와 같은 Component이다 (이외에 Box, Sphere 등등 다양하게 존재한다)

 

Capsule Component는 USceneComponent를 상속받은 UCapsuleComponent클래스 이다

 

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Components/CapsuleComponent.h" //헤더파일 include 시 항상 generated.h 보다 위에 선언해야 한다, 보통 .h에서는 필요한 class를 전방선언으로 처리한다
#include "Bird.generated.h"

class UCapsuleComponent; //전방선언

//.h에서 필요한 class를 include하지 않고 전방선언을 해야하는 이유는 inlcude하게 되면 모든 .h에 있는 코드를 include하기 때문에 커지게 된다
//따라서 무분별한 .h include는 지양해야한다

//각각의 .h파일이 서로를 include하게 되면 순환 종속성 error가 발생하게 된다 따라서 전방선언을 사용해야 한다
//ex) A.h가 B.h를 include하고 B.h가 A.h를 include하는 상황

//컴파일러는 해당 class가 사용될 것이라는걸 알면 되기 때문에 전방선언으로도 충분하다
//include하지 않고 전방선언만 했을 시 해당 class내부의 함수나 변수 사용은 불가능하며 객체 생성도 불가능하다

//cpp에서 사용할 때 include해주면 된다

//헤더파일 include를 하게 되면 해당 클래스에서 추가로 선언한 .h파일들도 같이 include되게 된다 (코드가 복잡해진다)

//.h파일에서 꼭 include 해야 하는 상황으로는 부모 클래스를 상속받았을 때 해당 부모 클래스를 include 해주어야 한다
//그 외에도 CoreMinimal.h, generated.h 등이 있다
//추가로 .h에서 해당 class 내부의 변수,함수에 접근하거나 객체 생성을 해야할 때는 include 해주어야 한다

 

private:
	UPROPERTY(VisibleAnywhere)
	UCapsuleComponent* Capsule; //UCapusleComponent*로 CapsuleComponent 선언

 

ABird::ABird()
{
	PrimaryActorTick.bCanEverTick = true;

	//CreateDefaultSubobject<>()로 Component생성
	Capsule = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
	
   	//RootComponent로 지정
	SetRootComponent(Capsule);
}

 

SetRootComponent() : 원하는 SceneComponent를 RootComponent로 지정할 수 있다

 

SceneComponent (USceneComponent*) 를 인자로 가진다

 

이와 같은 CapsuleComponent가 생성되었다

 

CapsuleHeight, CapsuleRadius로 높이, 반지름을 조절할 수 있다 (Mesh의 모양에 맞게 조절해서 사용)

 

Capsule->SetCapsuleHalfHeight(20.f);
Capsule->SetCapsuleRadius(15.f);

SetCapsuleHalfHeight() : Capsule의 절반 높이를 조절한다

 

HalfHeight (float), 겹칠때 이벤트를 발생시킬지? (true면 overlap 시 무언가와 겹치는지 확인하고 이벤트를 호출할 수 있다) (bool)을 인자로 가진다

 

SetCapsuleRadius() : Capsule의 반지름을 조절한다

 

Radius (float), 겹칠때 이벤트를 발생시킬지? (true면 overlap 시 무언가와 겹치는지 확인하고 이벤트를 호출할 수 있다) (bool)을 인자로 가진다

 

 

3. SkeletalMesh Component

 

StaticMeshComponent는 애니메이션을 적용할 수 없다, 하지만 SkeletalMeshComponent는 애니메이션을 적용할 수 있다

 

SkeletalMeshComponent는 USkeletalMeshComponent이다 마찬가지로 USceneComponent를 상속받는 class이다

 

USkeletaMeshComponent는 USkeletalMesh (Mesh)를 가지고 있고 Skeleton을 가지고 있어 Animation을 적용할 수 있는것이다

 

SkeletalMesh 파일에서 Skeleton구조를 확인할 수 있다

이와 같이 직접 Bone을 제어할 수 있다

 

Animation Asset을 열어 Animation을 확인하고 제어할 수 있다

 

Skeleton Asset을 열어 Bone구조를 확인하고 제어할 수 있다 Preview Scene Setting -> Mesh를 변경하여 다른 SkeletalMesh로 적용도 가능하다 (Skeleton 구조가 동일해야 함)

 

UPROPERTY(VisibleAnywhere)
USkeletalMeshComponent* BirdMesh; //USkeletalMeshComponent*로 SkeletalMeshComponent선언

 

ABird::ABird()
{
	PrimaryActorTick.bCanEverTick = true;

	Capsule = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
    
   	//CreateDefaultSubobject<>()로 USkeletalMeshComponent 생성
	BirdMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("BirdMesh"));

	Capsule->SetCapsuleHalfHeight(20.f);
	Capsule->SetCapsuleRadius(15.f);

	SetRootComponent(Capsule);

	BirdMesh->SetupAttachment(GetRootComponent()); //SetupAttachment()로 컴포넌트 Attach
}

 

SetupAttachment() : 원하는 Component를 원하는 Component에 Attach해준다

 

TargetComponent (USceneComponent*), TargetComponent의 SocketName (FName) (Component는 Socket을 가질 수 있으며 그 해당 Socket의 Name을 의미한다)을 인자로 가진다

 

GetRootComponent() : RootComponent를 USceneComponent*로 반환한다

 

생성한 SkeletalMeshComponent가 RootComponent에 Attach되었다

 

Mesh -> SkeletalMeshAsset에서 원하는 SkeletalMesh Asset을 적용할 수 있다

 

원하는 SkeletalMeshAsset이 적용되었다

 

SkeletalMeshComponent -> Animation에서 원하는 Animation을 적용할 수 있다 (StaticMeshComponent에는 존재하지 않는다)

 

728x90
반응형