Unity

Addressable Asset (6) - Download Progress 처리

CCS_Cheese 2025. 2. 16. 17:28

이번 게시글에서는 Addressable Asset의 bundle pack을 다운로드할 때 현재 다운로드 상태를 나타내는 Progress를 작업해 보겠습니다.

 

Unity 공식 AsyncOperationHandle

 

Asynchronous operation handles | Addressables | 1.21.21

Asynchronous operation handles Many tasks in the Addressables need to load or download information before they can return a result. To avoid blocking program execution, Addressables implements such tasks as asynchronous operations. In contrast to a synchro

docs.unity3d.com

 

Download 진행률 모니터링

AsyncOperationHandle 

  • GetDownloadStatus : DownloadStatus Struct를 리턴하여 정보 모니터링.
  • DownloadStatus(Struct) : (현재 다운로드된 Byte, TotalByte) 및 percentage의 정보를 가지고 포함하는 Struct 구조
  • AsyncOperationHandle.PercentComplete : 전체 OperationHandle의 Percentage return, 각 하위 operation 별 byte 크기는 고려하지 않고 같은 가중치로 percentage 환산
AsyncOperationHandle.PercentComplete
각 Operation 여기서는 Prefab, Sound bundle pack이 각각 2MB, 10MB라고 할 때 두 개의 하위 작업의 각각의 Byte의 크기가 다른데 이를 같은 가중치를 놓고 percentage를 환산하는 방식으로 각 작업이 끝났을 때 return 되는 percentage는 50%로 return 됨을 알 수 있습니다.

 

DownloadDependenciesAsync(Keys)의 한계

내부적으로 각 Key별로 bundle file을 다운로드할 때 현재 다운로드되고 있는 label(key)를 알 수 없어 현재 Sound를 다운로드하고 있는지, Prefab을 다운로드하고 있는지 알 수가 없습니다. 이를 해결하기 위해 아래와 같이 변경하여 표시할 수 있습니다.
public async Task<bool> DownloadDependencySingle()
{
    foreach (string key in Keys)
    {
        progress.Initalize();
        progress.SetProgressName(key);
        progress.Show();
        try
        {
            AsyncOperationHandle handle = Addressables.DownloadDependenciesAsync(key, false);

            while (!handle.IsDone)
            {
                DownloadStatus status = handle.GetDownloadStatus();
                progress.SetProgress(status.Percent);
                Debug.Log($"Key{key}\n{key}TotalBytes{status.TotalBytes}\nCurrentDownloadedBytes{status.DownloadedBytes}\nNeedDownloadBytes{status.TotalBytes - status.DownloadedBytes}");
                await Task.Yield();
            }
            handle.Release();
        }
        catch (Exception error)
        {
            Debug.LogError(error.Message);
            progress.Hide();
            return false;
        }
    }
    progress.Hide();
    return true;
}

 

각 Key별로 단일 Dependency를 다운로드하여, 현재 다운로드 중인 bundle의 key를 Progress상에 보여주고, 해당 AsyncOperationHandle의 Status를 활용하여 Total, Downloaded, Percentage를 확인하여 Progress를 표시해 줄 수 있습니다.

작업이 완료되면 Progress를 Hide 하여 Load를 구현하였습니다.

 

이어서, 더 큰 파일을 이용하여 다운로드가 잘되는지 확인하고, 별도의 빌드 없이 bundle이 변경되었을 때 정상적으로 다운로드가 되는지 확인해 보겠습니다.

 

 

. fbx 파일들을 프로젝트에 추가한 뒤 해당 fbx를 addressable 그룹을 만들어 추가한 뒤 빌드를 하면 다음과 같습니다.

 

.fbx들을 addressable 추가한 상태
fbxs.bundle 이 추가된 상태

해당 bundle 파일들을 서버에 업로드 한 뒤 runtime에 이제 Load 해보겠습니다.

bundle 다운로드

 

Addressables.DownloadDependency를 통해 현재 percentage를 Progress로 표기하여 얼마나 다운로드하였는지 출력하는 방식으로 Progress를 구현하였습니다.

Key를 통한 Instantiate

 

정리하자면 아래와 같습니다.

 

1. Addressable을 바로 Addressables.Instantiate를 하게 될 때 내부적으로 Dependency가 다운로드되어 있지 않으면 해당 Key에 관련이 있는 bundle을 다운로드하고 Instance를 한다.

2. 만약 해당 Key의 bundle의 dependency가 이미 다운로드가 되어 있다면 별도의 다운로드 없이 key를 통해 바로 Instantiate를 한다.

 

빌드를 한 뒤 bundle 파일이 교체된 상태에서 같은 key를 다운로드하는 것을 보도록 하겠습니다.

 

Key : Assets/AssetStore/FBXs/Composition_50.fbx
Key : Assets/AssetStore/FBXs/Composition_50.fbx

 

위 두 가지의 이미지에서 볼 수 있듯이 Key는 그대로 사용하고 bundle (Addressable Group)의 해당 key로 다른 asset을 빌드해서 서버에 올리게 되면 빌드를 하지 않고 asset을 변경할 수 있는 것을 볼 수 있습니다. 

'Unity' 카테고리의 다른 글

Unity Git hub Acitons - 2 (Workflow 작성)  (0) 2025.02.25
Unity Git hub Actions - 1 (개념 정리)  (0) 2025.02.25
Unity Addressable Asset (5)  (0) 2025.02.13
C# 델리게이트(Delegate) in Unity  (0) 2025.01.29
Unity Runtime Memory 관리 - 1  (1) 2025.01.12