게임 개발/Unreal Engine 기본

Unreal Engine 비동기 로딩

지노윈 2026. 1. 2. 14:03
반응형

비동기 로딩은 게임의 끊김(Stuttering)을 방지하는 핵심 기술입니다. TSoftObjectPtr을 실제 프로젝트에서 효과적으로 사용하는 두 가지 핵심 방법(C++와 블루프린트)을 정리해 드릴게요.


1. C++: FStreamableManager를 이용한 비동기 로딩

가장 권장되는 방식입니다. 엔진의 전역 매니저를 사용하여 백그라운드 스레드에서 에셋을 로드하고, 완료되면 콜백 함수를 실행합니다.

[코드 예시]

// Header (.h)
UPROPERTY(EditAnywhere, Category = "Assets")
TSoftObjectPtr<UStaticMesh> SubMeshPtr;

void OnMeshLoaded(); // 로드 완료 후 실행될 함수

// Source (.cpp)
void AMyActor::StartAsyncLoad()
{
    if (SubMeshPtr.IsPending())
    {
        // 1. 스트리밍 매니저 가져오기 (보통 GameInstance나 전역으로 관리)
        FStreamableManager& AssetLoader = UAssetManager::GetStreamableManager();
        
        // 2. 비동기 로드 요청
        AssetLoader.RequestAsyncLoad(SubMeshPtr.ToSoftObjectPath(), 
            FStreamableDelegate::CreateUObject(this, &AMyActor::OnMeshLoaded));
    }
}

void AMyActor::OnMeshLoaded()
{
    // 3. 로드가 완료되었으므로 Get()을 통해 실제 포인터를 가져옴
    UStaticMesh* LoadedMesh = SubMeshPtr.Get();
    if (LoadedMesh)
    {
        MyMeshComponent->SetStaticMesh(LoadedMesh);
        UE_LOG(LogTemp, Log, TEXT("Async Load Complete!"));
    }
}

2. 블루프린트: Async Load Asset 노드 사용

C++보다 훨씬 직관적이며, 복잡한 로직이 필요 없는 UI나 간단한 액터 로직에 자주 쓰입니다.

  1. 변수 생성: 변수 타입을 원하는 객체(예: Static Mesh)의 Soft Object Reference로 설정합니다.
  2. 노드 배치: Async Load Asset 노드를 배치하고 Soft Object Reference를 연결합니다.
  3. 완료 처리: Completed 핀이 실행되면, Get Asset 노드를 통해 로드된 객체를 사용합니다.

3. 실무 활용 팁: "언제 로드하고 언제 해제할까?"

TSoftObjectPtr을 효율적으로 쓰기 위한 전략입니다.

  • 인벤토리 시스템: 아이템 데이터 테이블에는 모든 아이콘을 TSoftObjectPtr로 담아둡니다. 인벤토리 창을 열 때만 화면에 보이는 아이콘들을 비동기 로드하고, 창을 닫으면 참조를 해제(null 대입)하여 메모리를 확보합니다.
  • 보스전: 플레이어가 보스 방 근처 트리거에 진입했을 때 보스의 고해상도 메쉬와 이펙트를 로드하기 시작합니다.
  • 참조 해제: TSoftObjectPtr 자체는 스마트 포인터이므로, 이를 소유한 클래스가 파괴되거나 해당 변수에 다른 값을 넣으면 가비지 컬렉터(GC)가 판단하여 메모리에서 해제합니다.

4. 주의사항: "Hard Reference"를 조심하세요!

만약 TSoftObjectPtr 변수를 선언해두고, 코드 어딘가에서 이 변수를 일반 포인터(UStaticMesh*) 변수에 담아버리면, 그 즉시 하드 참조가 되어 비동기 로딩의 이점이 사라집니다. 로드가 끝난 후에도 필요한 짧은 순간에만 지역 변수로 받아 쓰고, 멤버 변수로는 계속 TSoftObjectPtr 상태를 유지하는 것이 좋습니다.

반응형