Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

3냥 집사이면서 게임 개발자입니다.

언리얼 오브젝트 관리 2 - 패키지 본문

Unreal Engine 5/언리얼 C++

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

훙이야 2023. 7. 28. 14:40

언리얼 엔진의 에셋과 이를 포장한 패키지의 개념의 이해, 언리얼 에디터에서 볼 수 있도록 에셋을 저장하고 불러들이는 방법의 이해와 오브젝트 패스를 사용해 다양한 방식으로 에셋을 로딩하는 방법에 대한 이해를 정리하고자 합니다.

 

언리얼 오브젝트 패키지

- 단일 언리얼 오브젝트가 가진 정보는 저장할 수 있지만, 오브젝트들이 조합되어 있다면?

     - 저장된 언리얼 오브젝트 데이터를 효과적으로 찾고 관리하는 방법은?

     - 복잡한 계층 구조를 가진 언리얼 오브젝트를 효과적으로 저장과 불러들이는 방법을 통일해야 합니다.

- 언리얼 엔진은 이를 위해 패키지(UPackage) 단위로 언리얼 오브젝트를 관리합니다.

- 패키지의 중의적 개념

     - 언리얼 엔진은 다양한 곳에서 단어 패키지를 사용하고 있습니다.

     - 언리얼 오브젝트를 감싼 포장 오브젝트를 의미합니다. (이번 글의 주제입니다.)

     - 또한 개발된 최종 컨텐츠를 정리해 프로그램으로 만드는 작업을 의미합니다. ( 예) 게임 패키징)

     - DLC와 같이 향후 확장 컨텐츠에 사용되는 별도의 데이터 묶음을 의미하기도 합니다. ( 예) pkg 파일)

 

* 구분을 위해 언리얼 오브젝트 패키지로 부르는 것도 고려해야 합니다.

 

패키지(Package) 와 에셋 (Asset)

- 언리얼 오브젝트 패키지는 다수의 언리얼 오브젝트를 포장하는데 사용하는 언리얼 오브젝트입니다.

     - 모든 언리얼 오브젝트는 패키지에 소속되어 있습니다. ( 예) Transient Package)

- 언리얼 오브젝트 패키지의 서브 오브젝트를 에셋(Asset) 이라고 하며 에디터에는 이들이 노출됩니다.

- 구조상 패키지는 다수의 언리얼 오브젝트를 소유할 수 있으나, 일반적으로는 하나의 에셋만 가집니다.

- 에셋은 다시 다수의 서브 오브젝트를 사질 수 있으며, 모두 언리얼 오브젝트 패키지에 포함됩니다.

     - 하지만 에디터에는 노출되지 않습니다.

 

패키지를 사용해서 언리얼 에디터에서 볼 수 있는 에셋을 저장해보겠습니다.

이전 포스팅에서 사용했던 직렬화 프로젝트를 이어서 사용합니다.

패키지를 저장하는 코드입니다. 이렇게 저장했을 때 에디터에서 패키지에 저장된 에셋을 표시해줍니다.

에디터에 보여지는 이름은 패키지의 첫 번째 에셋 이름인 TopStudent 가 나옵니다. 

이어서 로드하는 코드를 작업합니다.

저장했던 패키지를 패키지 이름으로 찾고, FullyLoad 함수를 사용해 모든 에셋을 로드합니다. 

PrintStudentInfo 함수를 실행함으로써 저장했던 에셋의 정보를 출력합니다.

언리얼 엔진 에디터 출력 결과
LoadPackage 함수 안에 추가한 코드

GetObjectsWithOuter 함수를 호출하면 자신을 Outer 로 설정한 모든 서브 오브젝트를 얻어올 수 있습니다. 

위에서 저장한 10개의 서브 오브젝트를 얻어와 출력해보겠습니다. 

언리얼 엔진 에디터 출력 결과

 

에셋 참조와 로딩

에셋 정보의 저장과 로딩 전략

- 게임 제작 단계에서 에셋 간의 연결 작업을 위해 직접 패키지를 불러 할당하는 작업은 부하가 큽니다.

     - 에셋 로딩 대신 패키지와 오브젝트를 지정한 문자열을 대체해 사용합니다. 이를 오브젝트 경로라고 합니다.

     - 프로젝트 내에 오브젝트 경로값은 유일함을 보장합니다.

     - 그렇기에 오브젝트 간의 연결은 오브젝트 경로 값으로 기록될 수 있습니다.

     - 오브젝트 경로를 사용해 다양한 방법으로 에셋을 로딩할 수 있습니다.

- 에셋의 로딩 전략

     - 프로젝트에서 에셋이 반드시 필요한 경우 : 생성자 코드에서 미리 로딩합니다.

     - 런타임에서 필요한 때 바로 로딩하는 경우 : 런타임 로직에서 정적 로딩합니다.

     - 런타임에서 비동기적으로 로딩하는 경우 : 런타임 로직에서 관리자를 사용해 비동기 로딩합니다.

 

 

오브젝트 경로 (Object Path) ( 에셋을 로딩하기 위해 직접 지정)

- 패키지 이름과 에셋 이름을 한 데 묶은 문자열입니다.

- 에셋 클래스 정보는 생략할 수 있습니다.

- 패키지 내 데이터를 모두 로드하지 않고 오브젝트 경로를 사용해 필요한 에셋만 로드할 수 있습니다.

 

{에셋클래스정보}'{패키지이름}.{에셋이름}'

또는 

{패키지이름}.{에셋이름}

에셋 스트리밍 관리자 (Streamable Manager)

- 에셋의 비동기 로딩을 지원하는 관리자 객체

- 콘텐츠 제작과 무관한 싱글턴 클래스에 FStreamableManager를 선언해두면 좋습니다.

     - GameInstance는 좋은 선택지

- FStreamableManager를 활용해 에셋의 동기/비동기 로딩을 관리할 수 있습니다. 

- 다수의 오브젝트 경로를 입력해 다수의 에셋을 로딩하는 것도 가능합니다.

 

오브젝트 경로를 사용해 에셋을 동기/ 비동기 로딩하는 작업해보겠습니다.

GameInstance 클래스에 함수를 추가했습니다.
멤버 변수로 스트리밍 매니저와 핸들을 추가합니다.
기존에 저장해둔 패키지 이름과 에셋 이름으로 LoadObject합니다.

생성자에서 오브젝트 경로로 에셋을 로드합니다.

생성자 코드에서 지정한 에셋이 존재하지 않는 경우, 시작할 때 강력한 경고와 에러메세지가 뜹니다.

따라서 생성자 코드에서 로드하는 에셋은 반드시 존재하는지 확인해야 합니다.

그 다음엔 StreamableManger 를 사용해 에셋을 비동기로딩합니다.

 

언리얼 엔진 에디터 출력 결과

Constructor 태그가 달린 언리얼 에셋이 로딩된 것을 확인할 수 있는데, 두 번 로그가 찍혀있는 것을 확인할 수 있습니다.

첫 번째는 에디터가 로딩될 때, 두 번째는 에디터 내 게임이 실행될 때 Constructor에 관련된 함수들이 호출되어 두 번 찍힙니다. 

오브젝트 경로를 사용해 LoadObject 함수로 패키지 전부가 아닌 필요한 에셋만 불러오는 편리한 방식을 사용해봤습니다.

그리고 에셋 스트리밍 관리자를 사용해 에셋을 비동기 로딩하는 과정까지 살펴봤습니다.

 

 

언리얼 오브젝트 패키지 정리 

1. 언리얼 오브젝트 패키지 구조를 이해할 수 있었습니다.

2. 패키지 클래스를 사용해서 에셋 데이터를 생성하고 불러들이는 방법을 이해했습니다.

3. 오브젝트 경로의 설계와 이를 활용한 다양한 에셋 로딩 방법을 이해할 수 있었습니다. 

 

 

 

 

 

 

 

참고 사이트(언리얼 문서)

https://docs.unrealengine.com/5.1/ko/referencing-assets-in-unreal-engine/

 

애셋 참조

 

docs.unrealengine.com