나만의 작은 도서관
[TIL][C++] 250522 MMO 서버 개발 23일차: 언리얼 C++ 클래스 기본 구조 알아보기, 프로젝트 빌드 전, Unreal Header Tool(UHT) 사용의 전반적인 흐름 등등… 본문
Today I Learn
[TIL][C++] 250522 MMO 서버 개발 23일차: 언리얼 C++ 클래스 기본 구조 알아보기, 프로젝트 빌드 전, Unreal Header Tool(UHT) 사용의 전반적인 흐름 등등…
pledge24 2025. 5. 23. 01:02주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다.
언리얼 C++ 클래스 기본 구조 알아보기
#pragma once
#include "CoreMinimal.h"
#include "P1.h"
#include "P1GameInstance.generated.h"
UCLASS()
class P1_API UP1GameInstance : public UGameInstance
{
GENERATED_BODY()
};
#include “CoreMinimal.h”
- 언리얼 엔진의 핵심 기능들을 포함하는 헤더. 자주 사용되는 기능들(FString, TArray, UE_LOG, check() 등…)이 포함된 헤더들을 모아둔 헤더이다.
- 즉, 알고리즘 문제를 풀 때 bits/stdc++.h와 같은 기능을 하는 헤더이다.(좀 더 컴팩트하겠지만…)
- 엔진 개발에 필수적인 최소한의 헤더들을 포함하는 기본헤더이기 때문에 클래스 추가 시 자동으로 넣어주는 것이다.
#include "XXX.generated.h"
- 이 헤더는 Unreal Header Tool, 일명 UHT가 자동 생성한 코드들이 포함한 파일이다.
- UCLASS(), USTRUCT() 등의 매크로를 처리하기 위해 사용하며, 처리된 매크로는 언리얼의 리플렉션 시스템에 등록된다.
- 참고로 이 헤더는 반드시 마지막 헤더 파일로써 존재해야 한다.(안 그러면 오류 난다)
- 컴파일 시 UHT가 이 파일을 생성한다.
- 요약: 언리얼을 리플렉션 및 직렬화 시스템을 위해 자동 생성된 코드를 포함
GENERATED_BODY
- UCLASS, USTRUCT, UENUM 등에 의해 선언된 클래스/구조체/열거형의 리플렉션 정보를 자동 생성된 코드와 연결하는 매크로이다.
- XXX.generated.h에 의해 생성된 코드들이 이 GENERATED_BODY()에 들어간다.
- 반드시 클래스 선언 내에 포함되어야 하며, 일반적으로 생성자 선언 앞에 위치한다.
UCLASS()
- 이 클래스가 언리얼 엔진의 객체 시스템(Object System)에 참여함을 나타내는 매크로
- Uobject를 상속한 모든 클래스는 UCLASS()로 선언되어야 한다.
- Blueprintable, EditInlineNew, Abstract 등 다양한 메타 옵션을 지정할 수 있다.
UCLASS(Blueprintable, Abstract)
class MYGAME_API AMyActor : public AActor
- 요약: 언리얼 리플렉션 시스템과 블루프린트 통합을 위한 클래스 선언 마커
XXX_API
- 언리얼의 모듈 시스템에서 클래스나 함수의 외부 공개 여부를 제어하는 매크로.
- 빌드 타깃 모듈의 이름에 _API를 붙인 형태로 자동 생성된다.
- DLL 인터페이스(윈도우에서는 __declspec(dllexport)또는 __declspec(dllimport)를 설정하는 역할을 한다.
- 해당 모듈 내에서 빌드할 땐 dllexport, 다른 모듈에서 참조할 땐 dllimport로 처리됨
코드 설명 요약
#include "CoreMinimal.h" | 필수 엔진 타입과 매크로 포함 |
#include "XXX.generated.h" | UHT 생성 코드 포함 (반드시 마지막 줄) |
GENERATED_BODY | 리플렉션 시스템 연결 매크로 |
UCLASS() | UObject 기반 클래스 정의 마커 |
XXX_API | 모듈 간 공개 여부 정의 |
프로젝트 빌드 전, Unreal Header Tool(UHT) 사용의 전반적인 흐름
- 개발자가 UCLASS / USTRUCT / UFUNCTION 등의 “정의 마커”를 코드에 작성
- 빌드 시 파일에서 정의 마커를 발견했다면, Unreal Build Tool이 UHT를 호출
- UHT는 메타 데이터를 분석하여 xxx.generated.h 파일을 생성
- GENERATED_BODY()에 generated.h 파일에서 제공하는 코드를 삽입
- ⇒ 리플렉션, 블루프린트 연동, 직렬화 등이 가능해진다.
- =============================
- 프로젝트 빌드(전처리 → 컴파일) 시작
리플렉션 시스템
- C++은 컴파일 시점에서 타입 정보를 제거하기 때문에, 런타임에서 클래스나 변수의 구조를 알 수 없다.
- 따라서, 언리얼은 자체 도구인 UHT를 사용해 C++ 클래스에 메터데이터(metadata)를 주입하는 “리플렉션 시스템”을 이용해 런타임에도 구조를 알 수 있도록 한다.
기능 설명
에디터 노출 | UPROPERTY(EditAnywhere) 같은 매크로를 통해 변수들이 디테일 패널에 표시됨 |
블루프린트 통합 | UFUNCTION(BlueprintCallable) 같은 매크로로 함수와 변수를 블루프린트에서 호출 가능 |
직렬화 (Serialization) | 객체를 저장/불러오기 할 때 자동으로 필드 값을 처리 |
복제/네트워킹 | Replicated 속성을 지정하면 변수 동기화 처리 가능 |
런타임 타입 정보 | IsA(), GetClass(), FindObject() 등으로 객체 탐색 및 타입 확인 가능 |
GC (Garbage Collection) | UPROPERTY로 등록된 객체는 자동으로 참조 추적되어 메모리 관리됨 |
코드 예시
UCLASS()
class MYGAME_API AMyActor : public AActor
{
GENERATED_BODY()
public:
// 디테일 패널에 노출됨
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
float Health;
// 블루프린트에서 호출 가능
UFUNCTION(BlueprintCallable, Category = "Actions")
void Jump();
};
- Health 변수는 에디터에서 수정 가능
- Jump() 함수는 블루프린트에서 호출 가능
- 이 클래스는 FindObject, NewObject, IsA() 등으로 런타임에서 접근 가능