[UE5] 이득우 Part 1. 8강 언리얼 C++Ⅱ - 컴포지션

공부 스파이럴·2023년 12월 9일
0

컴포지션

  • 객체 지향 설계에서 상속이 가진 Is-A 관계만 의존해서는 설계와 유지보수가 어려움
  • 컴포지션은 객체 지향 설계에서 Has-A 관계를 구현하는 설계 방법

SOLID 기법

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

실습 예시

  • 출입증 기능
    • 출입증을 부모에서 구현해 상속 or 컴포지션 분리

    • 새로운 자식이 생기면 부모를 수정해야될 수도 있음
      • 부모를 수정하면 기존 자식들에게 문제가 생길 수도 있음
    • 그러므로 컴포지션으로 분리하는 것이 바람직
      • 단순히 컴포지션으로 구현하는 것이 아니라 모던 객체지향 언어가 제공하는 고급 기법들을 활용해야 함

언리얼 엔진에서의 컴포지션

  • 언리얼 오브젝트를 조합하는 방법
    1. 필수적 포함: CDO에 미리 언리얼 오브젝트를 생성해 조합
      • CreateDefaultSubobject() 사용
    2. 선택적 포함: CDO에 빈 포인터만 넣고 런타임에 언리얼 오브젝트를 생성해 조합
      • NewObject() 사용

  • 언리얼 오브젝트는 생성할 때 컴포지션 정보를 자동으로 구축해 줌
    • 내가 소유한 언리얼 오브젝트: Subobject
    • 나를 소유한 언리얼 오브젝트: Outer

실습

  • 오브젝트 구분 -> enum class
    • 열거형 E 접두사
    • uint8로 해주는 것이 일반적
    • UENUM() 매크로를 통해서 언리얼 엔진을 통해 유용한 정보를 가져올 수 있게 됨
      • 열거형의 각 데이터마다 메타 정보를 넣고 사용할 수 있음
      • UMETA(DisplayName = "For Student")

  • 컴포지션의 경우 헤더를 포함하기 보다는 전방선언
    • 보통 오브젝트는 포인터로 관리하기 때문에 전방선언을 통해서 의존성을 최대한 없앨 수 있음

언리얼 엔진 5 마이그레이션 가이드 5.0

https://docs.unrealengine.com/5.0/ko/unreal-engine-5-migration-guide/

  • 근데 언리얼 5부터 새로운 가이드가 생김
  • UPROPERTY 변수에 원시 포인터가 있었던 선언들을 TObejectPtr을 통해서 변경해서 사용
    • 선택 사항이지만 권장
    • 선언에서 사용하고 구현부에서는 그냥 포인터 써도 됨

  • 초기화 단계에서 CreateDefaultSubobject를 통해서 해야 함
    • 첫 번째 인자는 FNAME 식별자
      • 일반 스트링이 아니라 FNAME인 것을 구분하고 싶으면 접두사에 NAME_를 붙여 줌
  • 부모에서 CreateDefaultSubobject를 했으면 자식에선 setter만 호출해주면 됨

  • FindObject를 통해서 열거형 타입을 가져옴
    FindObject<UEnum>(nullptr,
    TEXT("/Script/프로젝트 이름.열거형 이름"));
    • Script 주소 안에 모듈 이름 == 프로젝트 이름
    • 모듈 이름에서 타입 이름을 통해서 정보를 얻어 옴
  • GetDisplayNameTextByValue 함수를 통해서 메타 데이터를 가져옴 + ToString()

0개의 댓글