득이공간

[언리얼 C++의 이해] 4장. 언리얼 프로젝트의 애셋과 빌드 시스템 본문

GP/UE5

[언리얼 C++의 이해] 4장. 언리얼 프로젝트의 애셋과 빌드 시스템

쟁득 2024. 1. 31. 21:08
해당 게시물은 이득우 교수님의 '언리얼 C++의 이해' 강의를 수강하며
학습한 내용을 개인적으로 정리한 글입니다.

📌 목차 - 4장. 언리얼 프로젝트의 애셋과 빌드 시스템

4-1. 언리얼 오브젝트 관리 1 - 직렬화
4-2. 언리얼 오브젝트 관리 2 - 패키지
4-3. 언리얼 빌드 시스템


📌 4-1. 언리얼 오브젝트 관리 1 - 직렬화

1. 언리얼 엔진이 제공하는 직렬화 시스템에 대한 이해
2. FArchive 클래스를 활용한 메모리 아카이브와 파일 아카이브의 활용
3. JSonSerializer를 활용한 JSON 형식의 직렬화 기능의 활용
4. 일반 C++ 객체 관리를 위한 언리얼 스마트 포인터 라이브러리 활용

 

* 직렬화 (Serialization)
- 오브젝트 or 오브젝트 그래프를 바이트 스트림으로 변환하는 과정이다.
- Serialization <-> Deserialization
- 게임의 저장, 멀티플레이어 게임 등에 사용된다.

* 언리얼 엔진 직렬화 시스템
- FArchive 클래스: 메모리 아카이브, 파일 아카이브
- Shift(<<) operator

* 직렬화 버퍼: TArray<uint8> BufferArray;

* Json(JavaScript Object Notation) 직렬화
- 언리얼 엔진의 Json, JsonUtilities 라이브러리 활용
- #include "JsonObjectConverter.h"
- Project.Build.cs 파일에서 Json 라이브러리(모듈) 연동 추가 // "Json", "JsonUtilities"
- 장점
텍스트임에도 데이터 크기가 가볍다.
읽기 편해서 데이터를 보고 이해할 수 있다.
사실 상 웹 통신의 표준으로 널리 사용된다.
- 단점
지원하는 타입이 몇가지 안된다. (문자, 숫자, 불리언, 널, 배열, 오브젝트만 사용 가능)
텍스트 형식으로만 사용할 수 있다.

* Json 데이터 유형
- 오브젝트: {} // { "key" : 10 }
- 배열: [] // [ "value1", "value2", "value3" ]
- ex.
{
"Name" : "이득우",
"Order" : 59
}

* 언리얼 스마트 포인터 라이브러리
- TUniquePtr: 지정한 곳에서만 메모리를 관리하는 포인터
- TSharedPtr: 더 이상 사용되지 않으면 자동으로 메모리를 해지하는 포인터
- TSharedRef: TSharedPtr와 동일하지만, 유효한 객체를 항상 보장받는다.

* 파일 아카이브 실습
- 데이터 저장
1. 저장할 파일 폴더 경로 생성
2. FArchive* <= FileWriter 생성 // TUniquePtr 사용
3. 시프트 연산자로 파일 아카이브를 통해 파일 작성
- 데이터 불러오기
1. 불러올 파일 경로 생성
2. FArchive* <= FileReader 생성 // TUniquePtr 사용
3. 시프트 연산자로 파일 아카이브를 통해 파일 로드

* 메모리 아카이브 실습
- 데이터 저장
1. 저장할 파일 폴더 경로 생성
2. FMemoryWriter로 오브젝트 직렬화 호출 -> 직렬화 버퍼에 저장 // TArray<uint8>
3. 직렬화 버퍼로 '파일 아카이브' 저장
- 데이터 불러오기
1. 불러올 파일 폴더 경로 생성
2. 직렬화 버퍼에 '파일 아카이브' 불러오기
3. FMemoryReader로 오브젝트 직렬화 호출

* Json 직렬화 실습
- 데이터 저장
1. 저장할 파일 폴더 경로 생성
2. FJsonObject 생성 후 오브젝트 정보 저장 // FJsonObjectConverter // TSharedRef 사용
3. TJsonWriter<TCHAR> <= WriterFactory로 생성 // TSharderRef 사용
4. FJsonSerializer로 FJsonObject를 직렬화 -> JsonString
5. FFileHelper로 JsonString 저장
- 데이터 불러오기
1. 불러올 파일 폴더 경로 생성
2. FFileHelper로 JsonString으로 불러오기
3. TJsonReader<TCHAR> <= ReaderFactory로 생성 // TSharedRef 사용
4. FJsonSerializer로 FJsonObject로 직렬화
5. FJsonObject를 오브젝트에 불러오기 // FJsonObjectConverter


📌 4-2. 언리얼 오브젝트 관리 2 - 패키지

1. 언리얼 오브젝트 패키지 구조의 이해
2. 패키지 클래스를 사용한 애셋 데이터의 관리
3. 오브젝트 경로의 설계와 이를 활용한 다양한 애셋 로딩 방법의 이해

 

* 언리얼 오브젝트 패키지
- UPackage: 오브젝트들의 조합, 포장 오브젝트
- UAsset: UPackage의 서브 오브젝트, 에디터에 노출됨

* 애셋 저장, 로딩
- 오브젝트 경로값을 이용: 오브젝트 애셋의 키값
- 프로젝트에서 반드시 필요한 경우: 생성자 코드에서 로딩 (엔진 초기화시 실행된다.)
- 런타임에서 필요할 때 바로 사용하는 경우: 런타임 로직에서 정적 로딩
- 런타임에서 비동기적으로 로딩하는 경우: 런타임 로직에서 관리자를 사용해 비동기 로딩

* 오브젝트 경로
- {애셋클래스정보}'{패키지이름}.{애셋이름}'
- 또는 {패키지이름}.{애셋이름}

* 애셋 참조
- 강 참조: 생성자 코드에서 로딩
- 약 참조: 간접 프로퍼티 참조

* 애셋 스트리밍 관리자(Streamable Manager)
- 애셋의 비동기 로딩을 지원하는 관리자 객체다.


📌 4-3. 언리얼 빌드 시스템

1. uproject 명세서를 사용한 언리얼 에디터 동작 원리
2. 언리얼 엔진의 모듈 시스템과 소스 코드 관리 방법
3. 모듈 작업 분리를 위한 플러그인 시스템
4. 언리얼 소스코드의 구조
5. 게임 빌드의 설정과 게임 패키징 과정

 

* 언리얼 엔진의 구성
- 에디터: 게임 제작을 위해 제공되는 응용 프로그램
- 게임 빌드: EXE 파일과 리소스로 이루어진 독립적으로 동작하는 게임 클라이언트
- 언리얼 에디터에서 게임을 구성 -> 게임 빌드를 수행하고 프로그램을 패키징

* 언리얼 에디터의 동작
- .uproject -> UnrealVersionSelector -> UnrealEditor
- .uproject: 에디터를 띄우기 위한 명세서, Json 형식으로 구성되어 있다.

* 언리얼 C++ 모듈
- 에디터 용: DLL 동적 라이브러리 // UnrealEditor-{모듈이름}.DLL
- 게임 용: 정적 라이브러리

* 언리얼 C++ 모듈 추가하기
- Binaries/Win64 폴더에 해당 DLL을 넣는다.
- 빌드된 모듈 목록이 있는 UnrealEditor.modules 파일도 같은 폴더에 넣는다.
- uproject 명세서에 모듈 이름을 지정한다.
"Modules" : [
{
"Name" : "UnrealSerialization",
"Type" : "Runtime"
}
]

* 모듈 C++ 코드의 관리
- 소스 코드(Source 폴더) -> Unreal Build Tool(C# 프로그램) -> OS(컴파일러 실행)

* Source 폴더의 구조
- 타깃 설정 파일 // {프로젝트이름}.Target.cs - 게임빌드, {프로젝트이름}Editor.Target.cs - 에디터빌드
- 모듈 폴더: 모듈 설정 파일, 소스 코드 파일 // 모듈설정파일: {모듈이름}.Build.cs

* 게임 프로젝트의 소스
- {모듈이름}.h, {모듈이름}.cpp
- 모듈의 뼈대
1. IMPLEMENT_MODULE: 일반 모듈
2. IMPLEMENT_GAME_MODULE: 게임 모듈
3. IMPLEMENT_PRIMARY_GAME_MODULE: 주 게임 모듈

* Generate Visual Studio project files: Source 폴더 내부 변화에 따라 솔루션 재생성

* 모듈간의 종속 관계
- GameModule <- SubModule (플러그인으로 분리)
ㄴ Engine / JsonUtilities
ㄴ CoreUObject / Json
ㄴ Core

* 모듈의 공개와 참조
- 주 게임 모듈: 게임 로직
- 서브 모듈: Public 폴더 및 API 매크로(주 게임 모듈이 Build.cs 설정을 통한 참조), Private 폴더

* 플러그인 구조
- 플러그인 명세서 (uplugin 파일)
- 플러그인 리소스 (Resource 폴더, 에디터 메뉴용 아이콘)
- 콘텐츠
- 모듈 폴더

* 게임 빌드
- 게임 타깃 설정 추가(게임 빌드 옵션 추가) -> 빌드된 모듈은 정적 라이브러리로 실행 파일에 포함된다.
- 빌드: 실행 파일을 생성하기 위한 컴파일
- 쿠킹: 지정한 플랫폼에 맞추어 콘텐츠 애셋을 변환하는 작업
- 패키징: 이들을 모두 모아서 하나의 프로그램으로 만드는 작업
- 게임 패키지 (실행 파일, 콘텐츠 파일)

* Shipping 빌드: 최종 게임의 코드를 만들어내는 작업, 모든 코드 최적화

* 최종 패키징
- Platforms -> Windows -> Package Project(shipping)->Package폴더지정
- 빌드와 쿠킹을 모두 진행한다.