[이득우의 언리얼] 8. 언리얼의 C++ 설계 - 컴포지션

2026. 2. 6. 15:20·기타/[강의] 이득우의 언리얼 프로그래밍 Part1

개요

이번 강의에서는 Unreal Engine C++만의 독특한 컴포지션(Composition) 기법을 사용하여 복잡한 Unreal Object를 효과적으로 설계하고 생성하는 방법을 학습합니다. 학교 시스템에 출입증 카드를 추가하면서 Has-A 관계를 구현하고, Unreal Engine의 확장 열거형 타입을 활용하는 방법을 익힙니다.

 

학습 목표

  • Unreal C++ 컴포지션 기법을 사용한 객체의 포함 관계 설정 방법 학습
  • CreateDefaultSubobject와 NewObject API의 차이점 이해
  • Unreal Engine의 확장 열거형 타입 선언 및 활용 방법 습득
  • 메타데이터를 활용한 런타임 정보 추출 방법 학습

 

컴포지션이란 ?

1. 상속 (Inheritance) - Is-A 관계

class UStudent : public UPerson  // 학생은 사람이다 (IS-A)
{
};

 

 

2. 컴포지션 (Composition) - Has-A 관계

class UPerson
{
    UCard* Card;  // 사람은 카드를 소유한다 (HAS-A)
};

 


 

SOLID 원칙

좋은 객체지향 설계를 위한 5가지 원칙:

1. Single Responsibility Principle (단일 책임 원칙)
하나의 객체는 하나의 책임만 가져야 함
예: UCard는 카드 정보만 관리

2. Open-Closed Principle (개방-폐쇄 원칙)
확장에는 열려있고, 수정에는 닫혀있어야 함
기존 코드 변경 없이 새 기능 추가 가능

3. Liskov Substitution Principle (리스코프 치환 원칙)
자식 객체를 부모 객체로 치환해도 동작해야 함
상속 구조를 단순하게 유지

4. Interface Segregation Principle (인터페이스 분리 원칙)
큰 인터페이스를 작은 단위로 분리
예: ILessonInterface, IDamageable 등으로 분리

5. Dependency Inversion Principle (의존성 역전 원칙)
구체적인 구현보다 추상적인 개념에 의존
예: 특정 캐릭터보다 캐릭터의 역할에 의존

 


 

Unreal에서의 컴포지션 구현

CDO와 컴포지션

Unreal Object는 항상 CDO(Class Default Object)와 1:1 매칭됩니다. 컴포지션 구현 시 두 가지 선택지가 있습니다:

 

방식1 : CDO에 미리 생성 (필수적 포함)

// 생성자에서 서브 오브젝트 생성
UPerson::UPerson()
{
    Card = CreateDefaultSubobject<UCard>(TEXT("Card"));
    // 모든 Person 인스턴스는 항상 Card를 가짐
}

특징:

  • 생성자 코드에서 실행
  • CreateDefaultSubobject 사용
  • 필수적으로 포함되는 컴포넌트

 

방식2 : 런타임에 동적 생성 (선택적 포함)

// 필요할 때 생성
void UPerson::IssueCard()
{
    if (!Card)
    {
        Card = NewObject<UCard>(this);
    }
}

특징:

  • 런타임 코드에서 실행
  • 'NewObject' 사용
  • 선택적으로 포함되는 컴포넌트

 


 

Unreal 확장 열거형

/**
 * 카드 타입을 나타내는 열거형입니다.
 */
UENUM(BlueprintType)
enum class ECardType : uint8
{
    /** 학생용 카드입니다. */
    Student     UMETA(DisplayName = "For Student"),
    
    /** 교사용 카드입니다. */
    Teacher     UMETA(DisplayName = "For Teacher"),
    
    /** 교직원용 카드입니다. */
    Staff       UMETA(DisplayName = "For Staff"),
    
    /** 유효하지 않은 카드입니다. */
    Invalid     UMETA(DisplayName = "Invalid")
};

 

출력 방법

// ===== 방법 1: 열거형 값 직접 출력 =====
for (auto Person : Persons)
{
    // 카드 타입 가져오기
    UCard* PersonCard = Person->GetCard();
    check(PersonCard);  // 반드시 존재해야 함 (필수 컴포지션)
        
    ECardType CardType = PersonCard->GetCardType();
        
    // 열거형을 정수로 출력
    UE_LOG(LogTemp, Log, TEXT("%s님이 소유한 카드 종류: %d"), 
           *Person->GetName(), 
           static_cast<int32>(CardType));
}
// ===== 방법 2: 메타데이터 활용 =====
// 열거형 타입 정보 가져오기
const UEnum* CardEnumType = FindObject<UEnum>(
    nullptr, 
    TEXT("/Script/UnrealComposition.ECardType")
);
    
if (CardEnumType)
{
    for (auto Person : Persons)
    {
        UCard* PersonCard = Person->GetCard();
        check(PersonCard);
            
        ECardType CardType = PersonCard->GetCardType();
            
        // DisplayName 메타데이터 추출
        FString CardMetaData = CardEnumType->GetDisplayNameTextByValue(
            static_cast<int64>(CardType)
        ).ToString();
            
        UE_LOG(LogTemp, Log, TEXT("%s님이 소유한 카드 종류: %s"), 
               *Person->GetName(), 
               *CardMetaData);
    }
}

'기타 > [강의] 이득우의 언리얼 프로그래밍 Part1' 카테고리의 다른 글

[이득우의 언리얼] 10. 언리얼 컨테이너 라이브러리 - TArray, TSet  (0) 2026.02.07
[이득우의 언리얼] 9. 언리얼 C++ 설계 - 델리게이트  (0) 2026.02.06
[이득우의 언리얼] 7. 언리얼 C++ 설계 - 인터페이스  (0) 2026.02.04
[이득우의 언리얼] 6.언리얼 오브젝트 리플렉션 시스템 2  (0) 2026.02.04
[이득우의 언리얼] 5. 언리얼 오브젝트 리플렉션 시스템 1  (0) 2026.02.03
'기타/[강의] 이득우의 언리얼 프로그래밍 Part1' 카테고리의 다른 글
  • [이득우의 언리얼] 10. 언리얼 컨테이너 라이브러리 - TArray, TSet
  • [이득우의 언리얼] 9. 언리얼 C++ 설계 - 델리게이트
  • [이득우의 언리얼] 7. 언리얼 C++ 설계 - 인터페이스
  • [이득우의 언리얼] 6.언리얼 오브젝트 리플렉션 시스템 2
Meoyoung's Development Logs
Meoyoung's Development Logs
내가 보려고 만든 블로그
  • Meoyoung's Development Logs
    이게뭐영
    Meoyoung's Development Logs
  • 전체
    오늘
    어제
    • 분류 전체보기 (229)
      • 게임잼 (3)
      • 언리얼 엔진 (53)
        • 꿀 Tip ! (7)
        • 트러블슈팅 (24)
        • 최적화 (0)
        • 캐릭터 (2)
        • VR (1)
        • Lighting (2)
        • 멀티스레드 (2)
        • 문자열 (0)
      • C++ (31)
        • 문법 정리 (8)
        • [서적] Fundamental C++ 프로그래밍 .. (5)
        • [서적] 이것이 C++이다 (11)
        • [서적] Effective C++ (7)
      • C# (1)
        • [서적] 이것이 C#이다 (1)
      • 코딩테스트 (26)
        • 프로그래머스 (6)
        • 알고리듬 (13)
        • 자료구조 (7)
      • 컴퓨터 과학 (27)
        • 운영체제 (11)
        • 데이터베이스 (0)
        • 디자인패턴 (0)
        • 자료구조 (5)
        • 네트워크 (0)
        • 컴퓨터구조 (11)
      • 면접준비 (0)
        • C++ (0)
        • 운영체제 (0)
        • 자료구조 (0)
      • 프로젝트 (25)
        • [팀프로젝트] The Fourth Descenda.. (5)
        • [개인프로젝트] FPS 구현 맛보기 (5)
        • GetOutOf (15)
      • 기타 (54)
        • [강의] 이득우의 언리얼 프로그래밍 Part1 (10)
        • [강의] 이득우의 언리얼 프로그래밍 Part3 (12)
        • [강의] 소울라이크 개발 A-Z (4)
        • [강의] Udemy-2D (5)
        • [서적] 인생 언리얼5 (4)
        • 스파르타코딩클럽 (15)
        • 객체지향프로그래밍 (2)
        • 컴퓨터회로 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    삽입정렬
    게임잼
    참가후기
    버블정렬
    게임개발
    쉘정렬
    경북게임잼
    알고리즘
    자료구조
    셸정렬
    선택정렬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Meoyoung's Development Logs
[이득우의 언리얼] 8. 언리얼의 C++ 설계 - 컴포지션
상단으로

티스토리툴바