마스터 반 Assignment01
UBT (Unreal Build Tool)
“언리얼 엔진의 빌드 총괄 매니저”
언리얼 엔진은 방대한 코드베이스를 가지고 있으며, 윈도우, 맥, 콘솔, 모바일 등 수많은 플랫폼을 지원해야 합니다. 일반적인 Visual Studio의 빌드 시스템(MSBuild)만으로는 이를 감당하기 어렵기 때문에 에픽게임즈가 독자적으로 만든 C# 기반의 커스텀 빌드 시스템입니다.
주요 기능
- 빌드 환경 구성 및 타겟 설정:
*.Target.cs파일을 읽어 게임을 에디터용, 클라이언트용, 서버용 중 어떤 목적으로 빌드할지 결정합니다. - 모듈 의존성 관리:
*.Build.cs파일을 분석하여 내 게임 모듈이 엔진의 어떤 모듈(Core, Engine, InputCore 등)을 필요로 하는지 파악하고 연결해 줍니다. - 크로스 플랫폼 컴파일 지휘: 목표하는 플랫폼(Windows, Android, PS5 등)에 맞는 적절한 C++ 컴파일러(MSVC, Clang 등)를 찾아내어 컴파일 명령을 내립니다.
- 외부 툴(UHT) 호출 (중요): C++ 코드가 본격적으로 컴파일되기 전, UHT를 먼저 실행시키는 트리거 역할을 합니다.
관계성: UBT -> UHT
- UBT의 관점: 빌드가 실행되면 기본 C++에는 없는
UCLASS(),UPROPERTY()같은 언리얼 전용 매크로들이 있습니다. 하지만 UBT는 C#으로 만들어진 빌드 매니저라 이를 읽을 수가 없기 때문에 UHT(Unreal Header Tool)를 부르는 역할을 하게 됩니다. - 관계: UBT는 일반 C++ 컴파일러를 실행하기 전에 UHT를 실행시키는 주체입니다. UBT가 없으면 UHT는 언제 실행되어야 할지 알 수 없습니다. UBT가 파일의 변경 상태를 파악하고, UHT에게 매크로를 분석시켜 추가 코드(
.generated.h)를 생성하라고 명령을 내립니다.
UHT (Unreal Header Tool)
“언리얼 헤더 도구”
표준 C++ 컴파일러가 이해하지 못하는 언리얼 전용 매크로들을 해석하여, 엔진이 필요한 추가 코드를 대신 작성해 주는 역할을 합니다.
주요 기능
- 헤더 파일 파싱: 헤더 파일(
.h)을 분석하여UCLASS(),UPROPERTY(),UFUNCTION()등의 매크로를 찾아냅니다. - 코드 자동 생성: 리플렉션 시스템이 해당 클래스의 구조를 파악할 수 있도록
클래스명.generated.h와클래스명.gen.cpp파일을 생성합니다. 우리가 헤더 파일에#include "FileName.generated.h"를 반드시 넣어야 하는 이유가 이것입니다. - 구문 체크: 표준 C++ 문법에는 어긋나지 않더라도, 언리얼 엔진의 규칙(예: UCLASS 내부의 특정 제약 사항)에 어긋나는 코드가 있다면 컴파일러보다 먼저 에러를 발생시켜 알려줍니다.
관계성: UHT -> 리플렉션
- UHT의 관점: 표준 C++은 자기 자신의 구조(클래스 이름, 변수 종류 등)를 기억하는 능력(리플렉션)이 없습니다. 그래서 UHT가 컴파일 전에 원본 코드를 파고들어서 “이 클래스엔 이런 변수가 있고, 저 함수는 블루프린트에서 쓸 수 있다”는 메타데이터를
.gen.cpp파일에 적어줍니다. - 관계: UHT는 리플렉션 리플렉션 시스템을 작동시키게 만드는 직접적인 원동력이자 데이터 공급책입니다. 리플렉션은 런타임 기능이지만, 이 기능이 돌아가려면 클래스에 대한 방대한 정보가 필요합니다. UHT가 빌드 타임에 이 정보들을 추출하여 C++ 코드로 자동 생성해 주지 않는다면 리플렉션 시스템은 존재할 수 없습니다. (UHT가 없으면 시스템(리플렉션)도 없습니다.)
리플렉션
“프로그램 실행 중에 자기 자신의 구조를 들여다보는 거울”
C++은 원래 자기가 어떤 변수와 함수를 가지고 있는지 실행 중(Runtime)에는 잊어버리는 언어입니다. 하지만 언리얼 엔진의 리플렉션 시스템은 이 한계를 깨고, 프로그램이 실행 중에도 자기 자신의 구조(클래스 이름, 변수 타입, 함수 목록 등)를 파악하고 조작할 수 있게 해줍니다.
주요 기능
- 가비지 컬렉션 (GC): 메모리 관리를 자동으로 해줍니다. 리플렉션이 객체 간의 참조 관계를 감시하고 있기 때문에, 아무도 찾지 않는 쓰레기 객체를 안전하게 지울 수 있습니다.
- 블루프린트 연동: C++로 짠 코드(
UPROPERTY,UFUNCTION)를 에디터의 블루프린트 노드로 노출시킵니다. 리플렉션 데이터가 C++과 블루프린트 사이의 통역기 역할을 합니다. - 직렬화 (Serialization): 게임을 저장/불러오기 할 때, 리플렉션이 객체 안의 변수들을 스캔해서 나중에 그대로 복원할 수 있는 ‘바이트 덩어리’로 만들어 파일로 기록합니다.
- 네트워크 리플리케이션: 멀티플레이 게임에서 서버의 변수 값을 클라이언트에게 동기화할 때, 어떤 변수를 보내야 하는지 판단하고 처리합니다.
관계성: 리플렉션 -> CDO
- 리플렉션의 관점: 엔진이 켜지면 리플렉션은 UHT가 준 데이터를 읽고 클래스 정보를 인지합니다. 엔진이 “클래스 기본 템플릿(CDO)을 만들어야 하는데 어떻게 생겼어?”라고 물으면, 리플렉션이 가진 구조 정보를 제공합니다. 그걸 보고 엔진이 메모리에 가장 처음으로 찍어낸 틀이, CDO입니다.
- 관계: 리플렉션은 CDO를 생성하기 위한 ‘설계도(클래스 레이아웃)’를 제공하는 주체입니다. 엔진은 클래스를 메모리에 올릴 때, 클래스의 크기가 얼마인지, 어떤 변수가 초기화되어야 하는지 알아야 합니다. 리플렉션 시스템이 이 정보를 엔진에게 제공해야만 엔진이 CDO라는 마스터 템플릿을 정확하게 생성(Allocate 및 Initialize)할 수 있습니다.
CDO (Class Default Object)
“메모리에 하나씩만 만들어지는 클래스의 원본”
CDO는 언리얼 엔진이 초기화될 때 메모리에 하나씩만 만들어지는 클래스의 원본입니다. 개발자가 만든 모든 UClass는 반드시 자신만의 CDO를 가지며, 이는 게임이 종료될 때까지 메모리에 상주합니다.
주요 기능
- 초고속 객체 생성 (최적화의 핵심): 게임 중 몬스터나 수많은 투사체를 스폰할 때, 매번 빈 메모리를 할당받고 변수들을 일일이 초기화하는 것은 CPU 오버헤드가 큽니다. 언리얼은 새 객체를 스폰할 때 이미 완성되어 있는 CDO의 메모리 블록을 통째로 복사해 버려 객체 생성 속도를 극대화합니다.
- 기본값의 안전한 저장소: 어떤 캐릭터의 기본 체력이 100일 때, 게임 중 데미지를 입어 10이 되더라도 CDO의 체력은 영원히 100으로 유지됩니다. 만약 에디터나 코드에서 원상 복구가 필요할 때 엔진은 CDO를 보고 원래 값을 그대로 가져옵니다.
- 에디터와의 실시간 연동: 언리얼 에디터의 ‘디테일 패널’에서 클래스의 기본 수치를 수정하면, 그 값은 즉시 CDO에 반영됩니다. 이후 생성되는 모든 객체는 변경된 CDO를 복사해서 태어나게 됩니다.
직접적인 관계는 없지만 연관된 코어 흐름
위에서 다룬 직접적인 인과관계 외에도, 엔진이 굴러가기 위해 간접적으로 톱니바퀴처럼 맞물려 있는 연관성들입니다.
UBT와 리플렉션
UBT는 리플렉션 시스템 그 자체는 아닙니다. 하지만 리플렉션이 존재할 수 있도록 코드를 조립하고 빌드해 주며, 리플렉션 기능이 동작할 수 있도록 컴파일 환경을 세팅하는 자동화 프로세스를 담당합니다.
UBT와 CDO
UBT가 CDO를 직접 만들지는 않습니다. 하지만 UBT가 성공적으로 전체 빌드 프로세스(UHT 실행 -> 컴파일 -> 링크)를 마쳐야만, 비로소 엔진이 실행되면서 CDO를 무사히 생성할 수 있습니다.
UHT와 CDO
UHT가 게임 실행 중에 CDO를 직접 메모리에 올리는 것은 아닙니다. 하지만 UHT는 엔진이 CDO를 정확하게 생성할 수 있도록 클래스 메타데이터를 제공하는 역할을 합니다.
UHT가 UPROPERTY를 분석해 주지 않으면 변수 정보가 리플렉션에 등록되지 않고, 결국 CDO에도 해당 변수의 기본값이 정상적으로 할당되거나 관리될 수 없습니다. 즉, CDO 탄생의 핵심 전제 조건이 바로 UHT의 분석 결과물입니다.
언리얼 엔진의 코어 파이프라인 흐름
- UBT가 빌드를 시작하며 UHT를 호출합니다.
- UHT가 헤더의 매크로를 분석해 메타데이터 코드를 생성합니다.
- 생성된 데이터를 바탕으로 C++ 컴파일이 완료되면, 엔진 런타임에 리플렉션 시스템이 활성화됩니다.
- 엔진은 리플렉션의 정보를 바탕으로 메모리에 각 클래스의 원본인 CDO를 찍어내어 게임 실행 준비를 마칩니다.
