Epic C++ 코딩 표준
언리얼 엔진 5의 공식 코딩 컨벤션과 네이밍 규칙 마스터하기
네이밍 컨벤션
언리얼 엔진의 클래스, 변수, 함수 명명 규칙
언리얼 엔진은 PascalCase를 기본으로 사용하며, 타입에 따른 접두사 규칙이 있습니다.
| 타입 | 접두사 | 예시 |
|---|---|---|
| UObject 파생 클래스 | U | UMyComponent |
| Actor 파생 클래스 | A | AMyCharacter |
| SWidget 파생 클래스 | S | SMyWidget |
| 인터페이스 | I | IMyInterface |
| 구조체 (대부분) | F | FMyStruct |
| Enum | E | EMyEnum |
| Template 타입 | T | TArray, TMap |
| Boolean 변수 | b | bIsActive, bCanJump |
// 올바른 네이밍 예시
UCLASS()
class MYGAME_API APlayerCharacter : public ACharacter
{
GENERATED_BODY()
public:
// Boolean은 b 접두사
UPROPERTY(EditAnywhere)
bool bIsAlive = true;
// 명확한 의미 전달
UPROPERTY(VisibleAnywhere)
float MaxHealth = 100.0f;
UPROPERTY()
TObjectPtr<UHealthComponent> HealthComponent;
};
정수 및 문자열 타입
플랫폼 독립적인 타입 사용하기
정수 타입
// UE5는 C++20을 기본으로 사용
// 권장: 명시적 크기 타입 (직렬화/네트워크에서 필수)
int32 MyValue; // 32비트 정수
uint8 MyByte; // 8비트 부호없는 정수
int64 LargeValue; // 64비트 정수
uint32 UnsignedVal; // 32비트 부호없는 정수
// 지역 변수에서만 사용
int MyLocalVar; // 플랫폼에 따라 크기 다를 수 있음
문자열 타입 선택
FString
내부 문자열 처리, 조작이 필요한 경우
FString Message = TEXT("Hello");
Message += TEXT(" World");
FName
에셋 이름, 빠른 비교가 필요한 경우
FName AssetName = TEXT("SM_Rock");
// 해시 기반 O(1) 비교
FText
UI 표시, 로컬라이제이션 필수!
FText UIText = NSLOCTEXT(
"Game", "Welcome",
"환영합니다!");
UI에 FString을 직접 사용하면 로컬라이제이션이 불가능합니다. 반드시 FText를 사용하세요!
UE5 코딩 표준 핵심 규칙
TObjectPtr, IWYU, 모듈 구조
1. TObjectPtr 사용 (UE5 필수)
// Before (UE4 스타일) - 더 이상 권장하지 않음
UPROPERTY()
UCameraComponent* CameraComponent;
// After (UE5 표준) - 반드시 이 방식 사용!
UPROPERTY()
TObjectPtr<UCameraComponent> CameraComponent;
// TObjectPtr의 장점:
// 1. 에디터에서 접근 추적 가능
// 2. Lazy Loading 지원
// 3. Cook 시 최적화
2. Include What You Use (IWYU)
#pragma once
// Forward Declaration 적극 활용
class UHealthComponent;
class UInventoryComponent;
class AWeapon;
UCLASS()
class AMyCharacter : public ACharacter
{
GENERATED_BODY()
// 헤더에서는 포인터만 선언
UPROPERTY()
TObjectPtr<UHealthComponent> HealthComp;
};
#include "MyCharacter.h"
// 실제 사용하는 헤더만 cpp에서 include
#include "Components/HealthComponent.h"
#include "Components/InventoryComponent.h"
3. Public/Private 폴더 구조
MyModule/
├── Public/ // 외부 모듈에 노출할 헤더
│ ├── MyModule.h
│ └── MyPublicClass.h
├── Private/ // 내부 전용 헤더 및 cpp 파일
│ ├── MyModule.cpp
│ ├── MyPrivateClass.h
│ └── MyPrivateClass.cpp
└── MyModule.Build.cs
IWYU를 준수하고 Forward Declaration을 활용하면 빌드 시간을 크게 단축할 수 있습니다.
API 매크로와 모듈
모듈 간 클래스 노출 관리
// API 매크로는 필요한 클래스에만 적용!
// 모든 클래스에 추가하지 말 것
// 외부 모듈에서 사용해야 하는 클래스
UCLASS()
class MYGAME_API UPublicComponent : public UActorComponent
{
GENERATED_BODY()
};
// 모듈 내부에서만 사용하는 클래스 - API 매크로 불필요
UCLASS()
class UInternalHelper : public UObject
{
GENERATED_BODY()
};
// MinimalAPI: 타입만 노출, 구현은 숨김
UCLASS(MinimalAPI)
class UMinimalClass : public UObject
{
GENERATED_BODY()
public:
// 이 함수만 외부에 노출
MYGAME_API void ExportedFunction();
// 이 함수는 모듈 내부에서만 접근 가능
void InternalFunction();
};
베스트 프랙티스
실무에서 적용할 핵심 규칙들
- 네이밍 컨벤션 — A, U, F, E, I, S, T, b 접두사 완벽 숙지
- FString vs FName vs FText — 용도에 맞게 정확히 구분
- TObjectPtr 사용 — UE5에서는 raw 포인터 대신 TObjectPtr 필수
- UPROPERTY 필수 — UObject 참조는 반드시 마킹
- IWYU 최적화 — Forward Declaration으로 빌드 시간 단축
- 모듈 간 의존성 관리 — Public/Private 분리 철저히
- API 매크로 전략 — 필요한 클래스만 선별적 export
- 코드 리뷰 기준 수립 — 팀 코딩 표준 문서화
핵심 요약
- 네이밍 접두사 — 타입에 따라 A(Actor), U(UObject), F(Struct), E(Enum), I(Interface) 사용
- TObjectPtr 필수 — UE5에서 헤더 파일의 UObject 포인터는 TObjectPtr 사용
- 문자열 타입 구분 — 내부처리(FString), 식별자(FName), UI(FText)
- IWYU 원칙 — 필요한 헤더만 include, Forward Declaration 활용
- API 매크로 — 외부 모듈에 노출할 클래스에만 MYPROJECT_API 적용
Epic Games 공식 C++ 코딩 표준: Epic C++ Coding Standard
도전 과제
배운 내용을 직접 실습해보세요
새 C++ 클래스 ARPGPlayerCharacter를 생성하고, 모든 멤버 변수에 올바른 접두사(b, F, E, T)를 적용하세요. UPROPERTY로 Health(float), bIsAlive(bool), CharacterState(ECharacterState), Inventory(TArray)를 선언하세요.
RPG 캐릭터의 UI 표시 이름은 FText(NSLOCTEXT), 내부 식별자는 FName, 디버그 로그 메시지는 FString으로 각각 구현하세요. TEXT() 매크로를 올바르게 사용하세요.
RPG 프로젝트를 Core, Combat, Inventory, UI 모듈로 분리하고, 각 모듈의 Public/Private 폴더 구조를 설계하세요. Build.cs에서 모듈 간 의존성을 최소화하고, Forward Declaration을 활용하여 빌드 시간을 측정/비교하세요.