Composition (컴포지션)
- 객체지향 설계에서 상속이 가진 Is-A 관계만 의존해서는 설계와 유지보수가 힘들다.
- Composition은 객체지향 설계에서 Has-A 관계를 구현하는 설계 방법이다.
- Composition을 통해 거대한 클래스를 효과적으로 설계하는데 유용하게 사용할 수 있다.
Composition의 필요성
이전 글인 Interface의 Person과 Student, Teacher, Staff의 예제를 그대로 사용해서 설명한다.
현재 Person의 구성원을 보았을 때 모두 School Card가 필요해보여 Person내에 Card를 구현했다.
하지만 이후 Person에서 Card가 필요하지 않은 객체도 Person을 상속받게 되면 Card 또한 받는다.
이렇게 Is-A관계에서 Has-A 관계로 바꿔줘 객체지향에 어울리게 하는 방법이 Composition이다.
Unreal에서 Composition 구현 방법
- 하나의 Unreal Object는 항상 CDO(Create Default Object)를 가지고 있다.
- Unreal Object에 다른 Unreal Object를 조합할 때 2가지 선택지가 존재한다.
- CDO에 미리 언리얼 오브젝트를 생성해 조합. (언제나 필수적으로 포함)
생성자에서부터 추가가 되며 cpp에서 CreateDefaultSubobject()로 만들어준다. - CDO에 빈 포인터만 넣고 런타임에 언리얼 오브젝트를 생성해 조합. (필요할 때 선택적 포함)
게임 런타임동안 작동하는 코드에 NewObject()를 통해 생성한다. - CreateDefaultSubobject()와 NewObject()를 통해 내가 소유한 Object를 Subobject라고 하며
나를 소유한 Unreal Object는 Outer라고 한다.
위 과정은 결국 원래의 Object에 다른 Object를 추가하는 것이다.
헤더 파일에서 오브젝트를 받을 때 전방선언을 통해 헤더파일을 다 포함하지 않고 사용하며
보통 오브젝트는 *로 받아온다.
UE4까지는 다음과 같이 헤더파일에서 선언했었지만
UPROPERTY()
class UCard* Card;
UE5부터는 아래와 같은 방식으로 선언하라고 되어있다.
UPROEPRTY()
TObjectPtr<class UCard> Card;
TObjectPtr로 감싸서 사용하라고 되어있다. 아래 링크에서 C++ Object Pointer Properties를 보면 나와있다.
헤더파일에서만 다음과 같이 사용하고 cpp에서는 그냥 *만 사용해도 무관하다.
https://docs.unrealengine.com/5.0/en-US/unreal-engine-5-migration-guide/
Unreal Engine 5 Migration Guide
Steps and requirements for migrating your Unreal Engine 4 projects to Unreal Engine 5.
docs.unrealengine.com
enum UMETA 출력 방법
다음과 같이 UCard에 enum type이 정의가 되어있다.
UENUM()
enum class ECardType : uint8
{
Student = 1 UMETA(DisplayName = "For Student"),
Teacher UMETA(DisplayName = "For Teacher"),
Staff UMETA(DisplayName = "For Staff"),
Invaild
}
Student = 1 을 통해서 자동으로 Teacher에는 2, Staff에는 3이라는 값이 들어간다.
cpp에서 DisplayName을 출력하기 위해서 다음과 같은 과정이 필요하다.
//TEXT에 있는 절대 주소값을 이용해서 원하는 Type정보를 들고온다.
//C++에서 생성된 객체들은 /Script 라는 절대 주소를 가지고
//그 다음은 프로젝트 이름(모듈 이름)을 적어준다.
const UEnum* CardEnumType = FindObject<UEnum>(nullptr, TEXT("/Script/ProjectName.ECardType"));
if(CardEnumType){
//GetDisplayNameTextByValue는 int64값만 받기 때문에 int64로 Cast해준다.
FString CardMetaData =CardEnumType -> GetDisplayNameTextByValue((int64)CardType).ToString();
UE_LOG(LogTemp, Log, TEXT("%s"), *CardMetaData);
}
'Unreal 게임 개발 > Unreal 강의 개인 정리' 카테고리의 다른 글
Unreal Struct & Map (0) | 2024.01.03 |
---|---|
Unreal Delegate (0) | 2023.12.29 |
Unreal Interface (0) | 2023.12.27 |
Unreal 기본타입 및 문자열 (0) | 2023.12.26 |
Unreal Object Reflection System & UClass (0) | 2023.12.18 |