본문 바로가기

공부/이득우의 언리얼 프로그래밍

[Study] Part 1 - 언리얼 C++ 설계Ⅱ - 컴포지션 (8/15)

728x90
반응형

 

 

 

  • 정리
    • 컴포지션을 활용한 언리얼 오브젝트 설계
      1. 언리얼 C++은 컴포지션을 구현하는 독특한 패턴이 있다.
      2. 클래스 기본 객체를 생성하는 생성자 코드를 사용해 복잡한 언리얼 오브젝트를 생성할 수 있음
      3. 언리얼 C++ 컴포지션의 Has-A 관계에 사용되는 용어
        1. 내가 소유한 하위 오브젝트 : Subobject
        2. 나를 소유한 상위 오브젝트 : Outer
      4. 언리얼 C++이 제공하는 확장 열거형을 사용해 다양한 메타 정보를 넣고 활용할 수 있다.
    • 언리얼 C++의 컴포지션 기법은 게임의 복잡한 객체를 설계하고 생성할 때 유용하게 사용된다.

 

 

 

 

  • 컴포지션(Composition)
    • 객체 지향 설계에서 상속이 가진 Is-A 관계만 의존해서는 설계와 유지보수가 어려움
    • 컴포지션은 객체 지향 설계에서 Has-A 관계를 구현하는 설계 방법
    • 컴포지션의 활용
      • 복합적인 기능의 거대한 클래스를 효과적으로 설계하는데 유용하게 사용할 수 있음

 

 

 

 

  • 모던 객체 설계 기법과 컴포지션
    • 좋은 객체지향 설계 패턴을 제작하기 위한 모던 객체 설계 기법 (SOLID)
    • Single Responsibility Principle (단일 책임 원칙)
      • 하나의 객체하나의 의무만 가지도록 설계한다.
    • Open-Closed Principle (개방 폐쇄 원칙)
      • 기존에 구현된 코드를 변경하지 않으면서 새로운 기능을 추가할 수 있도록 설계한다.
    • Liskov Substitution Principle (리스코프 치환 원칙)
      • 자식 객체를 부모 객체로 변경해도 작동에 문제 없을 정도로 상속을 단순히 사용한다.
    • Interface Segregation Design (인터페이스 분리 원칙)
      • 객체가 구현해야 할 기능이 많다면 이들을 여러 개의 단순한 인터페이스들로 분리해 설계한다.
    • Dependency Injection Principle (의존성 역전 원칙)
      • 구현된 실물보다 구축해야 할 추상적 개념에 의존한다.

 

 

컴포지션 예시

 

  • Person이라는 상위 개념에 Card라는 기능을 추가하면 Student, Staff, Teacher는 자동으로 모두 Card를 상속받을 수 있겠지만, 새로운 인물이 등장했을 경우 일부 수정해줘야 한다. 그렇기 때문에 Card는 컴포지션으로 구현하는 편이 낫다.

 

 

 

  • 언리얼 엔진에서의 컴포지션 구현 방법
    • 하나의 언리얼 오브젝트에는 항상 클래스 기본 오브젝트 CDO가 있다.
    • 언리얼 오브젝트에 다른 언리얼 오브젝트를 조합할 때 다음의 선택지가 존재
      1. CDO에 미리 언리얼 오브젝트를 생성해 조합한다. (필수적 포함) - CreateDefaultSubobject()
      2. CDO빈 포인터만 넣고 런타임에서 언리얼 오브젝트를 생성해 조합한다. (선택적 포함) - NewObject()

 

 

Unreal에서의 열거형

 

  • UENUM()이라는 매크로로 지정을 해주면, 해당 필드마다 UMETA()를 통해 메타 정보를 입력해줄 수 있다.
  • 이를 코드에서 사용할 수 있다.

 

 

 

 

 

 

Card 오브젝트를 헤더파일이 아닌 전방선언으로 포함하는 모습 (UE4 기준)
Card 오브젝트를 헤더파일이 아닌 전방선언으로 포함하는 모습 (UE5 기준)

 

 

  • 보통 컴포지션관계에 있을 때는 헤더파일을 통해 포함시켜주기 보다는 전방 선언을 통해 의존성을 최대한 없애줄 수 있다.
    • class UCard* Card; // UE4까지는 정석
    • TObjectPtr<class UCard> Card; // UE5부터는 원시 포인터를 다음과 같이 사용하라고 표준문서에 등록되어 있음.

 

 

 

 

 

 

Getter

  • Getter를 사용할 땐 const를 사용하는게 좋다. 다만, FString&과 같이 리턴값을 레퍼런스로 받고 있으면, 반환값도 const로 반환해주어야 한다.

 

 

 

 

 

열거형의 메타 정보를 출력하기 위한 예시

 

 

 

 

  • UENUM으로 선언한 열거형 변수의 메타정보를 가져오기 위해서 FindObject함수를 사용
  • UEnum을 가져오기 위해서는 다음과 같이 열거형의 주소 정보를 가져와야 한다.
  • 일반적으로 Script라는 절대주소를 가지며, 프로젝트이름(UnrealComposition)을 주소로 가지고 있다.

 

 

 

 

 

 

해당 포스트는 인프런의 <이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해>
강의를 수강하고 정리한 내용입니다.
 

이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해 | 이득우 - 인프런

이득우 | 대기업 현업자들이 수강하는 언리얼 C++ 프로그래밍 전문 과정입니다. 언리얼 엔진 프로그래머라면 게임 개발전에 반드시 알아야 하는 언리얼 C++ 기초에 대해 알려드립니다., [사진] 언..................

www.inflearn.com

 

 

 

 

728x90