[UE4] 동기 / 비동기 에셋 로딩
개요
데이터 혹은 에셋을 로드할 때 동기나 비동기 같은 단어가 튀어나오곤 합니다.
동기와 비동기.
단어만으로는 딱 느낌이 오지 않는데요.
정확하게 어떻게 구분되는지, 또 어떻게 동작하는지 알아보도록 하겠습니다.
동기 / 비동기(synchronous / asynchronous)
우선 각각의 특징을 정리해 보도록 하겠습니다.
동기
메모리가 명령어를 처리하는 흐름, 즉 선형적인 처리를 의미합니다.
선형적이란 것도 조금 설명이 필요하겠는데요.
명령을 일렬로 쭉 줄세워서 차례로 처리해나가는 걸 선형적이라고 합니다.
장점은 순서대로 처리해 나가므로 직관적이라는 점입니다.(버그 수정에는 직관적임이 참 중요합니다.)
단점은 자원 소모가 큰 작업이라면 프리징을 수반할 수 있다는 점입니다.
비동기
메모리의 흐름과 동떨어진 병렬적, 비선형적인 처리를 의미합니다.
병렬적이란 선형적인 것과는 다르게 여러 개의 작업을 동시에 하겠다는 의미입니다.
처리되는 명령줄이 여러 라인이 있다고 볼 수 있겠네요.
장점은 해당 작업 중에도 다른 작업을 함께 처리할 수 있다는 점, 즉 로드 완료시까지 기다릴 필요가 없다는 점입니다.
단점은 처리 및 완료 시점이 균일하지 않기 때문에 언제든 예외가 발생할 수 있다는 점입니다.
언리얼 에셋 로딩
동기 로딩
동기는 위에서 충분히 설명한 것 같네요.
그렇다면 동기 로딩은 어떤 걸까요?
쉽게 말하자면 에셋을 로드하는 일반적인 방식들을 말합니다.
아래와 같은 방법들이 있습니다.
1. TSoftObjectPtr의 LoadSynchronous() 함수로 로딩
2. 템플릿 함수 LoadObject<>()를 통해 로딩
3. 전역 함수 StaticLoadObject()를 통해 로딩
4. FStreamingManager의 RequestSyncLoad를 통해 로딩
비동기 로딩
그렇다면 비동기 로딩은 어떤 식으로 해야 할까요?
FStreamableManager의 RequestAsyncLoad를 사용하는 것이 간단한 방법 중 하나입니다.
FSoftObjectPath ObjectPath;
void UTempObject::BeginPlay()
{
auto& StreamableMgr = UAssetManager::Get().GetStreamableManager();
StreamableMgr.RequestAsyncLoad(ObjectPath, FStreamableDelegate::CreateUObject(this, &UTempObject::AsyncComplete));
}
void UTempObject::AsyncComplete()
{
UE_LOG(LogTemp, Log, TEXT("로딩 성공");
TSoftObjectPtr<UObject> SoftPtr(ObjectPath);
SoftPtr.Get(); // 에셋 존재함 확인
}