폰 클래스는 액터클래스에서 상속받은 기능외에 추가 기능을 가지고 있다.
그 추가기능 중 중요한 기능은 객체에 입력에 따른 변화를 줄 수 있다는 것이다.
Bird 폰 Class를 생성해보자
그리고 만든 클래스에 기반한 블루프린트도 만들어주자
이제 충돌에 사용할 기본적인 캡슐을 먼저 만들어보자.
실제 메시를 통한 충돌 계산은 비용이 많이 드는 작업으로 캡슐같은 기본적인 모양으로 충돌을 감지한다.
이제 코드에서 추가해보자
일단 UCapsuleComponent 객체는 언리얼 헤더파일에서 Include를 해주어야하는데 이때 주의해야할 점은
항상 .generated.h이 제일 마지막에 위치해야한다는 것이다. 그렇지 않으면 오류가 발생하게 된다.
이유는 .generated.h파일이 리플랙션 시스템의 통합과 관련되어 있기 때문이다.
하지만 이러한 헤더파일은 각 객체에서 Include 작업을 하는 것은 안좋다.
이유는 후에 다루기로하자.
먼저 UCapsuleComponent 변수를 선언해주고 블루프린트상에 보일 수 있게 하자
이렇게만 했을 때는 그냥 포인터변수를 가지고 있는 것으로
우리는 이것을 실제로 쓰기위해 하위 객체를 통해 초기화 해주어야한다.
Bird.h
private:
UPROPERTY(VisibleAnywhere)
UCapsuleComponent* Capsule;
Bird.cpp
CreateAbstractDefaultSubobject를 통해 초기화해준다.
Capsule = CreateAbstractDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
SetRootComponent(Capsule);
생성된 모습
높이와 너비를 조절하려면 아래의 코드와 같이 사용하면 된다.
ABird::ABird()
{
PrimaryActorTick.bCanEverTick = true;
Capsule = CreateAbstractDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
Capsule->SetCapsuleHalfHeight(20.f);
Capsule->SetCapsuleRadius(15.f);
SetRootComponent(Capsule);
}
★★헤더파일은 각 객체에서 Include 작업을 하는 것은 안좋다.
이유 : 각 객체의 헤더파일에서 계속 헤더 파일을 참조하게 되면 각 객체를 호출 할때마다 호출할 헤더코드가 가지고 있는 또 다른 헤더파일에 관련된 코드를 호출하게 되기때문에 컴파일 시간이 길어진다.
그래서 이러한 문제점을 해결하기 위해
Forward Declaration- 전방선언을 사용한다.
전방선언은
전방 선언(Forward Declaration)은 컴파일러에게 특정 클래스, 구조체, 함수 등의 존재를 미리 알리는 선언으로 이를 통해 해당 객체가 나중에 정의될 것임을 알려준다. 단순히 컴파일러에게 "이 이름이 존재한다"는 것을 알려주는 역할
헤더파일에서 전방선언을 한 뒤
정확하게 사용하는 것은 cpp파일에서 헤더파일을 가져온 뒤 사용하게 된다.
정리하자면
문제점
- 컴파일 시간 증가: 헤더 파일을 여러 번 포함하면 컴파일러가 포함된 모든 헤더 파일을 다시 처리해야 합니다. 이는 특히 대규모 프로젝트에서 컴파일 시간을 크게 증가시킬 수 있습니다.
- 순환 종속성: 클래스들이 서로를 참조할 때, 헤더 파일에서 직접 #include를 사용하면 순환 종속성 문제가 발생할 수 있습니다. 이는 컴파일 오류를 초래할 수 있습니다.
- 의존성 증가: 불필요한 헤더 파일을 포함하면 파일 간의 의존성이 증가하여 코드 수정 시 많은 파일을 다시 컴파일해야 할 수 있습니다. 이는 코드 유지 보수를 어렵게 만듭니다.
- 코드 복잡성: 헤더 파일에 너무 많은 #include가 있으면 코드가 복잡해지고, 어떤 헤더 파일이 실제로 필요한지 파악하기 어려워집니다.
장점
- 컴파일 시간 단축: 헤더 파일을 덜 포함함으로써 컴파일러가 처리해야 할 파일의 양을 줄여 컴파일 시간을 단축할 수 있다
- 순환 종속성 해결: 클래스들이 서로를 참조하는 경우, 전방 선언을 통해 순환 종속성 문제를 해결할 수 있다
- 의존성 관리: 파일 간의 의존성을 줄여, 코드 수정 시 재컴파일되는 범위를 최소화할 수 있다
- 코드 명확성: 헤더 파일을 깔끔하게 유지하고, 필요한 정의만 소스 파일에서 포함하여 코드의 명확성을 높일 수 있다.
반드시 포함해야 할 경우:
- 부모 클래스에서 상속받을 때
- 부모 클래스의 멤버 변수와 함수를 사용할 수 있도록 하기 위해 헤더 파일을 포함한다.
- 타입의 크기가 필요할 때
- 클래스의 새로운 인스턴스를 생성해야 하는 경우, 해당 타입의 크기를 알아야 하므로 헤더 파일을 포함한다.
- 멤버 변수/함수에 접근할 때
- 클래스의 멤버 변수나 함수를 사용할 때는 해당 클래스의 정의를 알아야 하므로 헤더 파일을 포함한다.
이러한 경우를 제외하고는, 전방 선언을 사용하여 헤더 파일의 불필요한 포함을 피할 수 있다. 이를 통해 컴파일 시간을 단축하고, 코드의 의존성을 줄일 수 있다.
이제 코드를 수정해보자 밑의 코드를 헤더파일에서 지워주자
#include "Components/CapsuleComponent.h"
Bird.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Bird.generated.h"
class UCapsuleComponent; //전방선언
UCLASS()
class SLASH_API ABird : public APawn
{
GENERATED_BODY()
public:
ABird();
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
protected:
virtual void BeginPlay() override;
private:
UPROPERTY(VisibleAnywhere)
UCapsuleComponent* Capsule;
};
이제 본격적으로 Pawn클래스에 매쉬를 붙여보자
매쉬에는 static과 skeletal이 있는데 static은 말 그대로 정적인 애니메이션이 불가능한 매쉬이고 skeletal은 뼈대로 구성된 매쉬로 애니메이션이 가능하다.
먼저 헤더파일에 변수를 추가해주자 이때 변수는 전방선언으로 선언해주자
class USkeletalMeshComponent;
private:
UPROPERTY(VisibleAnywhere)
UCapsuleComponent* Capsule;
UPROPERTY(VisibleAnywhere)
USkeletalMeshComponent* BirdMesh;
그리고 이제 cpp파일에서 변수에 대한 초기화를 진행해주자
#include "Pawns/Bird.h"
#include "Components/CapsuleComponent.h"
#include "Components/SkeletalMeshComponent.h"
ABird::ABird()
{
PrimaryActorTick.bCanEverTick = true;
Capsule = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule"));
Capsule->SetCapsuleHalfHeight(20.f);
Capsule->SetCapsuleRadius(15.f);
SetRootComponent(Capsule);
BirdMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("BirdMesh"));
BirdMesh->SetupAttachment(GetRootComponent());
}
BirdMesh가 추가되었고 이제 메시에 Sk_Crow를 추가해주었다.
그리고 여기에 애니메이션모드를 Use Animation Asset으로 바꿔주고 애님을 붙여주자
'게임공부 > Unreal Engine' 카테고리의 다른 글
[Unreal Engine][C++]7. Character Class (0) | 2024.07.18 |
---|---|
[Unreal Engine][C++]6.움직이기 (1) | 2024.07.16 |
[Unreal Engine][C++]4. 캐릭터 움직이기 (1) | 2024.07.11 |
[Unreal Engine][C++]3. 디버그 (0) | 2024.07.10 |
[Unreal Engine][C++]2. C++살펴보기 (0) | 2024.07.09 |