Class Default Onbject(CDO)는 언리얼 엔진 실행 시 자동으로 생성되는 특별한 UObject 인스턴스로,
각 UClass의 기본값을 보관하고 새로운 객체 인스턴스 생성 시 초기화 템플릿 역할을 합니다.
즉, 새 인스턴스가 생성될 때마다 해당 클래스의 CDO를 복사하여 기본 속성 값과 상태를 초기화합니다.
이 덕분에 모든 인스턴스가 일관된 초기 상태를 가질 수 있습니다.
// 선언부
class UClass : public UStruct
{
public:
/** 클래스 기본 객체; 델타 직렬화 및 객체 초기화에 사용된다. */
TObjectPtr<UObject> ClassDefaultObject;
}
// 예시
// CDO 가져오기
UMyObject* DefaultObj = UMyObject::StaticClass()->GetDefaultObject<UMyObject>();
int DefaultHealth = DefaultObj->Health;
델타 직렬화
객체의 현재 값과 기본값(CDO)를 비교하여, 변경된 값만 저장하거나 전송하는 최적화된 직렬화 방식입니다.
이렇게 하면 클래스의 기본 인스턴스(CDO)에 접근하여 속성 값을 확인하거나,
객체를 만들지 않고도 기본 데이터를 참조할 수 있습니다.
CDO는 클래스의 기본값 저장소이자 데이터 최적화와 구성 확장의 중심 요소로,
메타데이터 관리, 네트워크 트래픽 절감, 저장 공간 절약, 설정 기반의 객체 구성 등
다양한 엔진 기능을 호율적으로 지원합니다.
기본 속성 값 및 동작 제공
null이 아닌 일관된 초기값을 가집니다.메타데이터 정보 저장
데이터 전송 저장 (네트워크 복제)
데이터 저장 공간 절약 (직렬화 최적화)
동일한 클래스의 여러 객체를 파일에 저장할 때, 각 개체의 전체 데이터를 저장하는 대신 CDO의 기본값과의 차이(델타)만 기록해 공간 차지를 최소화할 수 있습니다.
이 방식은 저장 용량을 최소화하고, 로딩 시에도 효율적인 데이터 복원을 가능하게 합니다.
데이터 구성 가능성
리플렉션(Reflection) 또는 프로퍼티 시스템(Property System)은
런타임(동적) 중에 클래스의 구조와 메타데이터를 검사하고 조작할 수 있는 기능을 말합니다.
이 시스템은 언리얼 엔진의 핵심 기능들의 근본적인 기반 메커니즘으로 작동합니다.
대표적으로 다음 기능들이 리플렉션을 통해 구현됩니다.
이를 통해 디자이너가 프로그래머의 C++ 로직을 직관적으로 활용할 수 있고,
개발 효율과 협업 생산성을 크게 향상됩니다.
리플렉션을 사용하는 모든 언리얼 C++ 클래스의 헤더 파일에는 반드시
#include "FileName.generated.h"
포함해야 합니다.
또한, 리플렉션 시스템에 클래스나 멤버를 등록하기 위해서는 다음 매크로를 사용합니다.
UCLASSUSTRUCTGENERATED_BODYENUMUFUNCTIONUPROPERTYUPROPERTY 로 선언할 필요는 없지만,리플렉션 시스템은 런타임 중에도 클래스와 객체를 동적으로 제어할 수 있는 기능을 제공합니다.
| 기능 | 설명 |
|---|---|
| 클래스 탐색 | FindClass(TEXT("MyClass")) |
| 변수 정보 조회 | FindPropertyByName(TEXT("Health")) |
| 변수 값 읽기/쓰기 | FProperty::GetValue_InContainer/SetValue_InContainer |
| 함수 탐색 및 호출 | FindFunctionByName() + ProcessEvent() |
// 사용 예시
// 리플렉션을 이용하여 객체 속성 접근 및 변경
FProperty* NewProperty = UMyObject::StaticClass()→FindPropertyByName(TEXT(”Name”));
//프로퍼티 값을 가져올 수 있음.
NewProperty→GetValue_InContainer(클래스 객체, &프로퍼티 자료형);
//프로퍼티 값을 바꿀 수 있음.
NewProperty→SetValue_InContainer(클래스 객체, &프로퍼티 자료형);
//리플렉션을 이용하여 특정 함수 실행
UFunction* DoFunc = MyObject->GetClass()->FindFunctionByName(TEXT("ChangeName"));
MyObject->ProcessEvent(DoFunc, nullptr);
언리얼 오브젝트(UObject)는 C++ 언어의 한계를 보완하고,
C#이나 Java 같은 현대적 객체지향 언어의 기능을 포함한 확장된 객체 시스템을 제공합니다.
즉, 단순한 C++ 클래스가 아닌 언리얼 엔진 전용 런타임 기능의 기반 클래스입니다.
UPROPERTY나 UFUNTION 등을 통해 런타임 중 클래스 정보와 프로퍼티를 탐색·조작언리얼 엔진의 가비지 컬렉션(GC)은 더 이상 참조되지 않는 UObject를 자동으로 탐색하고 메모리에서 해제하는 시스템입니다.
즉, 프로그래머가 직접 delete 하지 않아도, 엔진이 주기적으로 참조 관계를 분석하여 불필요한 객체를 정리합니다.
UObject 의 참조 관계를 그래프 형태로 분석하고,TWeakObjectPtr 로 선언해 약한 참조(Weak Reference)로 관리해야 합니다.AActor)는 Destroy() 를 호출해 삭제 요청을 하지만,Destroy() 가 호출되더라도 레벨에서 제거되었더라도 해당 액터에 대한 모든 레퍼런스가 해제될 때까지 가비지 컬렉션되지 않는다.Destory() 호출 -> 레벨에서 제거 -> 참조 해제 완료 -> GC 실행 시 해제 순서로 처리됩니다.IsValid() 는 포인터가 nullptr 이거나 GC로 이미 파괴된 객체인지 확인합니다.OnDestroy 이벤트에서 포인터를 정리하는 것이 바람직하며,IsValid() 는 보조적인 안전검사용으로만 사용하는 것이 좋습니다.UObject 는 반드시 NewObject<> 로 생성해야 엔진의 GC 관리 대상이 됩니다.
| 생성 방식 | 설명 | GC 관리 여부 |
|---|---|---|
new | 일반 C++ 객체 생성. 엔진의 GC에 등록되지 않아 메모리 누수 위험 | ❌ |
NewObject<T>() | 언리얼 엔진이 관리하는 객체 생성. 자동으로 GC 대상에 등록됨 | ✅ |
// ❌ 잘못된 예시 (GC 관리 안 됨)
MyObj* Obj = new MyObj();
// ✅ 올바른 예시 (GC 관리 대상)
UMyObj* Obj = NewObject<UMyObj>();