공식 문서1, 공식문서2 내용을 먼저 살펴보고 오시는 것을 권장드립니다. 잘못된 내용은 없어 보이고 정리도 깔끔하지만, 읽고 나서도 뭔가 찜찜한 느낌이 드실 수 있습니다. 그 찜찜함을 같이 느끼셨다면 지극히 자연스러운 반응이라고 생각합니다.
디버깅할 때 변수 값이 제대로 보이지 않는 경우가 있는데, 이는 보통 Release로 컴파일한 상태에서 디버깅을 하기 때문입니다.
디버그와 릴리즈 모드에서 가장 큰 차이점은 최적화 여부입니다. 최적화는 크게 두 부분에서 이루어지는데, 메모리 사용량을 줄이는 것과 코드 양을 줄이는 것입니다.
#include <iostream>
int main() {
int a = 5;
int b = 10;
// 릴리즈 모드에서는 이 줄이 최적화될 수 있습니다.
int result = (a + b) / 2;
std::cout << "Result: " << result << std::endl;
return 0;
}
int result = (a + b) / 2; 에서 변수 'a','b' 값이 Release 모드에서는 보이지 않을 수 있습니다. 변수 'a','b'가 다른 곳에서 사용되지 않아 상수 취급이 가능하기 때문에, 컴파일러가 변수를 위한 스택 공간을 확보하지 않고 해당 라인을 int result = 15 / 2; 로 변경할 수 있습니다. 이 경우 변수 'a','b' 자체가 어셈블리 코드에서 삭제됩니다.
이러한 현상은 특히 클래스 멤버 함수 안에서 디버깅할 때 두드러집니다. 간혹 클래스 멤버 변수들의 값 추적이 제대로 되지 않는 경우가 있는데, x64 아키텍처에서 Microsoft Visual C++ 컴파일러는 'class this pointer'를 ECX 레지스터에 저장하고, 디버거에서도 ECX 레지스터를 기반으로 값을 보여주게 됩니다. 그런데 레지스터는 매우 중요한 자원입니다. 사용 레지스터를 줄일 수 있으면 최적화 여지가 크게 늘어나기 때문에, ECX 레지스터를 재사용하는 경우가 많습니다. 그 결과 값이 제대로 보이지 않게 되는 것입니다.
Windows OS의 특징 중 하나가 DLL (Dynamic-Link Library)의 적극적인 사용입니다. 이름에서 알 수 있듯이 동적으로 코드를 붙였다가 분리할 수 있습니다. Windows 프로그래밍을 직접 해보시면 바로 확인하실 수 있는데, LoadLibrary로 DLL을 읽고 특정 Offset에 있는 함수를 실행하는 방식입니다. C++에서는 .lib를 이용하여 DLL에 있는 Class를 편리하게 가져다 쓸 수 있도록 지원하고 있습니다.
DLL에 있는 함수를 사용하기 위해서는 DLL을 만들 때 해당 함수를 노출시켜야 합니다. 노출된 함수는 DLL을 TextEditor로 열어보시면 알아볼 수 있는 형태로 기록되어 있습니다.
프로그래밍을 하다 보면 작성한 클래스 등에 다음과 같이 MYMODULE_API를 붙이게 됩니다. class EKUE54_API AMyActor : public AActor 이것이 DLL에 노출하고 또 불러오는 Keyword이며, 노출시킬 때(DLL 생성)와 사용할 때(Load DLL) 약간 다른 키워드를 사용하게 됩니다. 이 부분은 별도의 포스팅에서 추가로 다루도록 하겠습니다.
그렇다면 .uproject를 더블 클릭하여 에디터를 실행하면 내부적으로 어떻게 동작하는 걸까요? 정답은, UnrealEditor.exe가 실행되고 우리가 작성한 게임 코드가 UnrealEditor_MyModule.DLL로 빌드된 상태에서 로딩되어 작동하는 것입니다. 또는 MyModule.exe로 빌드하여 단독 실행이 가능하도록 만들 수도 있습니다.
이 내용들이 UnrealEngine Build Configuration을 이해하는 데 필요한 사전 지식입니다.
처음 언급한 '공식 문서'에 있는 네이밍을 먼저 살펴보겠습니다.

상당히 많은 항목이 있습니다. 위에서 'Debug'는 LauncherVersion Engine을 사용할 때는 표시되지 않으며, Git에서 소스를 받아 직접 엔진을 빌드해야 확인하실 수 있습니다.
이제 하나씩 풀어보겠습니다. 앞서 말씀드렸듯이 공식 문서가 틀린 내용은 없으므로, 지금부터의 설명이 다소 중복으로 느껴지실 수도 있습니다. 다만, 위 네이밍 규칙은 규칙성이 있으면서도 묘하게 탈규칙적인 부분이 있기 때문에, 의문을 갖기보다는 그대로 익혀두시는 것을 권장드립니다.
아래에서 Engine은 언리얼 배포 엔진을, Game은 우리가 보통 만드는 게임 콘텐츠 부분을 뜻합니다. LauncherVersion(InstalledVersion)은 Game만 변경할 수 있습니다. (Debug), (Release)는 위에서 말씀드린 컴파일 타입을 의미합니다.
엄밀히 말씀드리면 Development, Test, Shipping은 Release로 빌드하지만 세부 내용이 조금씩 다릅니다. 이는 Log, Profiling 기능을 어느 정도로 포함할 것인지에 따라 나뉘게 됩니다. 다만 컴파일 타입 자체는 동일합니다.
Client/Server는 Dedicated Server 기능과 관련이 있는 것으로, 여기서는 논외로 하겠습니다.
MyModule.exe로 단독 실행(위에서 뒤에 Editor가 붙지 않는 경우)할 때 필요한 내용 중 하나가, Contents(Asset)가 Cooking되어 있어야 한다는 점입니다. Cooking이란 날것의 리소스(.uasset)가 해당 실행 타겟에 필요한 내용으로 추려져서 변환되어 있는 상태를 뜻합니다. Cooking하지 않고 실행하시면 처음 보시게 되는 내용이

이와 같은 화면인데, GlobalShader가 Cooking되어 있지 않기 때문에 나타나는 것입니다. Cooking은 다음 위치에서 수행하실 수 있습니다.

실행하시면 다음과 같은 폴더가 생성됩니다.






