내일배움캠프 58일차 - 언리얼 C++ 심화: SoftRef와 동기/비동기로드, DataTable과 DataAsset
에셋을 C++에서 가져오는 방법
1) 프로퍼티 참조
UPROPERTY(EditAnywhere)를 붙여 블루프린트에서 할당하는 방식을 일컫는다.
2) 생성 시간 참조
생성자단계에서 ConstructorHelpers::FObjectFinder<타입>이름(TEXT("경로위치"))를 입력해 지정경로에 오브젝트와 오브젝트 클래스를 찾아서 로드하는 방식. .Successed()로 로드 여부를 확인할 수 있다.
3) 간접 프로퍼티 참조
SoftObjectPtr<Type> 을 사용해 할당하는 방식. 아래에서 설명하도록 한다.
TSoftObjectPtr(소프트 오브젝트 레퍼런스)
TSoftObjectPtr<UStaticMesh> MeshToLoad;
TSoftClassPtr<AActor> MyActor;
하드 레퍼런스(오브젝트 레퍼런스, 클래스 레퍼런스):
1) 타입 값 처음부터 로드.
2) 참조된 에셋 바로 사용가능.
3) 메모리 점유율 상승.
소프트 레퍼런스(소프트 오브젝트 레퍼런스, 소프트 클래스 레퍼런스):
1) 경로만 가지고 있음.
2) 로딩 전까지는 메모리 점유하지 않음.
3) 중간로딩으로 프레임드랍 발생가능성 있음(비동기방식 로드로 해결가능)
동기 로드
메인 스레드에서 로드를 하여 로드 중에는 다른 작업을 멈추므로 프레임드랍이 발생할 수 있다.
- SoftPtr.IsNull(): 객체가 nullptr인가?
- SoftPtr.IsValid(): 객체가 로드되어있는가?
- SoftPtr.LoadSynchronous(): 객체를 동기로드를 한다.
| TSoftObjectPtr<UStaticMesh> MySoftMesh를 BP에서 로드하는 코드 |
비동기 로드
원하는 시점에 서브 스레드로 로드를 하여 게임 진행에 영향을 주지 않으면서 로딩이 끝나면 특정 함수를 호출하는 방식이다.
#include "Engine/AssetManager.h"
#include "Engine/StreamableManager.h"
FStreamableManager& Streamable = UAssetManager::GetStreamableManager();
Streamable.RequestAsyncLoad(
SoftPtr.ToSoftObjectPath(),
FStreamableDelegate::CreateUObject(this, 함수)
);
DataTable
#include "Engine/DataTable.h"
DataAsset은 DataTable처럼 정보를 저장하는 에셋이지만 특히 무거운 메쉬, 텍스처, 사운드 등 실제 에셋을 불러올 때 주로 쓴다.
| DA를 등록할 때 에셋 매니저에 ID를 등록하여 로드할때 ID를 넘겨 로드한다. |
DataTable: 한눈에 보는 표
- 언제 쓰는가?
1) 아이템 1,000개의 공격력, 가격, 드랍률 등의 수치 데이터를 한눈에 관리할 때.
2) 기획자가 엑셀로 데이터를 편집하고 엔진으로 임포트(Import)할 때.
3) 레벨 1부터 100까지의 경험치 테이블처럼 순차적인 데이터를 관리할 때.
- 단점
: 특정 Row 하나만 쓰려고 해도 테이블 파일 전체를 메모리에 올려야함. (개별적 관리 어려움)
DataAsset: 개별 포장된 상품, 하나하나의 독립된 파일
- 언제 쓰는가?
1) 런타임 중 특정 아이템만 로드해야 할 때.
2) 무거운 메쉬, 텍스처, 사운드 등 실제 에셋과 연결되어 비동기로 불러와야할 때
- 단점
: 아이템이 1,000개면 파일도 1,000개라, 수치를 한꺼번에 비교하며 수정하기 불편함.
DataTable과 DataAsset은 서로 장단점이 명확하기 때문에 두 개를 섞어서 쓰는 방식을 권장한다.
DataAsset 사용법
1) PrimaryDataAsset 클래스 추가
2)추가한 PrimaryDataAsset 헤더에 해당 코드 사용
FPrimaryAssetID: 에셋 매니저가 특정 파일을 식별하기 위해 넘겨주는 ID.
meta = (AssetBundles = "TEXT"): 특정 그룹의 에셋만을 로드하기 위해 고안된 메타데이터.
FPrimaryAssetType: 에셋의 타입을 알려주며, 프로젝트 세팅에서 아래와 같이 타입을 추가할 수 있다.
| 프라이머리 에셋타입: 내가 접근할 때 사용할 에셋 타입의 이름 에셋 베이스 클래스: 모아두고자 하는 에셋의 Base 클래스 Directories: 로딩할 에셋이 있는 디렉토리 |
3) 해당 PrimaryDataAsset을 상속하는 DataAsset을 추가한다.
4) 생성한 DataAsset을 사용하는 액터를 하나 만들어서 비동기로드를 실행한다.
#include "Engine/AssetManager.h"
UAssetManager& AssetManager = UAssetManager::Get();
AssetManager.LoadPrimaryAsset(ItemToLoad, ※TArray<FName> Bundles, Delegate 함수);
댓글
댓글 쓰기