Google Play Asset Delivery 레퍼런스

Google PAD API용 API 레퍼런스 및 구현 가이드라인

Windows
MacOS
Linux

Google Play Asset Delivery(Google PAD) 는 에셋 팩을 디바이스에 설치한 후 전송하는 Google Play Store의 솔루션입니다. 본 솔루션은 Android App Bundle 배포 형식과 함께 사용해야 합니다. App Bundle에서 최초 설치에 필요한 코드 및 바이너리를 처리하며 최종 사용자에게 커스터마이징된 .apk를 배포하고, Play Asset Delivery 시스템은 .apk와 별개로 모델, 텍스처, 사운드, 셰이더, 기타 대용량 에셋 파일을 제공합니다. 덕분에 Google Play를 통해 앱을 배포할 때, 필요에 따라 콘텐츠를 전송함으로써 콘텐츠가 차지하는 공간을 관리할 수 있습니다.

Google Play Asset Delivery와 관련된 일반 정보는 공식 Android 문서(https://android-developers.googleblog.com/2020/06/introducing-google-play-asset-delivery.html)를 참조하세요.

언리얼 엔진 4.25 부터는 플러그인을 통한 Google PAD 통합 기능을 이용하여 진행 중인 프로젝트에서 이 시스템을 간단히 구현할 수 있습니다. 이 플러그인이 제공하는 함수 라이브러리는 다운로드를 관리하고 Play Asset Delivery 시스템의 정보를 요청하는 호출이 있습니다. `UGooglePADFunctionLibrary`는 C++와 블루프린트에서 이용할 수 있습니다.

Android App Bundle로 배포하는 방법에 대해 자세히 알아보려면 Android 프로젝트 패키징을 참조하세요.

Google PAD 플러그인 활성화하기

Google PAD 플러그인은 언리얼 에디터 플러그인(Plugins) 창의 Android 섹션에 있으며, 언리얼 엔진 4.25.0 이상 버전에서 기본으로 활성화되어 있습니다. Google PAD를 사용하려면 반드시 Android App Bundle을 패키징 형식으로 사용해야 합니다.

Google PAD 플러그인

플러그인을 완전히 활성화하려면 프로젝트 세팅(Project Settings) 을 열고, 플러그인(Plugins) > GooglePAD > 패키징(Packaging) 으로 이동합니다. 플러그인 활성화(Enable Plugin) 체크박스를 클릭하면, Android 프로젝트에서 처음부터 모듈을 사용할 수 있습니다.

Google PAD 플러그인 옵션

Google PAD를 install-time 에셋에 사용하려면 플랫폼(Platforms) > Android > APK 패키징(APK Packaging) 으로 이동해 .apk 안에 게임 데이터 패키징?(Package Data inside APK) 을 비활성화합니다. 그러면 주요 .obb 파일이 자동으로 install-time 에셋 팩 형태로 전송됩니다.

클릭하여 이미지 확대

에셋 팩 생성하기

Google PAD용 에셋 팩(Asset packs) 은 Android App Bundle 빌드 내부에서 패키징되며, 업로드되면 Google Play Store에서 관리합니다. 이 섹션에서는 App Bundle에 포함할 에셋 팩을 패키징하고 정리하는 방법을 설명합니다.

에셋 팩 전송 모드

청크(Chunk) 는 외부 에셋 정리를 위한 언리얼 엔진의 형식입니다. 청크 0은 게임의 기본 설치 파일, 나머지 청크는 게임의 주요 설치 외에 쓰이는 에셋을 포함하는 .pak 파일입니다.

Google PAD를 활용하려면 게임의 에셋을 청크로 그룹화한 뒤, 이 청크를 사용할 전송 모드에 기반해서 에셋 팩으로 그룹화해야 합니다. Google Play Asset Delivery는 다음과 같은 에셋 팩 전송 모드를 지원합니다.

전송 모드

파일 크기 제한(에셋 팩별로 적용)

설명

Install-Time

1 GB

설치 시 전송되는 에셋 팩입니다. 프로젝트의 주요 .obb 파일은 자동으로 이 에셋 팩의 번들이 됩니다.

Fast-Follow

512 MB

앱이 설치되면 자동으로 다운로드되는 에셋 팩입니다. 앱을 실행하지 않아도 다운로드됩니다. 프로젝트마다 하나의 Fast-Follow 에셋 팩만 허용됩니다.

On-Demand

512 MB

앱이 실행 중일 때 다운로드되는 에셋 팩입니다.

애플리케이션마다 총 50 개의 에셋 팩을 생성할 수 있습니다. Install-Time 및 Fast-Follow 에셋 팩은 프로젝트마다 하나만 보유할 수 있지만, On-Demand 에셋 팩은 50개를 넘지만 않으면 얼마든지 사용할 수 있습니다.

청크 생성하기

프로젝트 세팅(Project Settings) 을 열고 프로젝트(Project) > 패키징(Packaging)으로 이동하여 청크 생성(Generate Chunks)을 활성화합니다.

프로젝트 > 패키징 섹션에서 청크 생성 활성화

이제 에셋 매니저(asset manager) 혹은 프라이머리 에셋 라벨(primary asset labels) 로 에셋을 청크로 정리할 수 있습니다.

프라이머리 에셋 라벨은 콘텐츠 브라우저(Content Browser)에서 우클릭한 뒤 기타(Miscellaneous) > 데이터 에셋(Data Asset) 을 클릭하여 생성할 수 있습니다.

클릭하여 이미지 확대

그러면 데이터 에셋 클래스(Data Asset Class) 선택 창이 표시됩니다. PrimaryAssetLabel 을 선택하고 선택(Select) 을 클릭합니다.

클릭하여 이미지 확대

새 프라이머리 에셋 라벨의 이름을 지정한 뒤, 더블 클릭하여 정보를 편집합니다.

클릭하여 이미지 확대

내 디렉터리의 에셋에 라벨(Label Assets in my Directory) 을 활성화하여 동일한 폴더의 모든 에셋이 이 에셋 라벨에 속하도록 지정합니다. 청크 ID(Chunk ID) 를 0보다 큰 값으로 설정하여 이 라벨에 속한 에셋이 포함될 청크를 지정하세요. 명시적 에셋(Explicit Assets) 목록을 사용하는 에셋 라벨에도 에셋을 직접 추가할 수 있습니다.

에셋 매니저는 프로젝트 세팅(Project Settings)게임(Game) > 에셋 매니저(Asset Manager) 에 있습니다.

클릭하여 이미지 확대

여기에서는 프로젝트에서 에셋을 청크에 절차적 으로 그룹화할 때 사용할 규칙을 지정할 수 있습니다. 자세한 정보는 쿠킹 및 청킹(Cooking and Chunking) 페이지를 참조하세요.

특정 청크에 포함시킬 에셋을 지정한 뒤 프로젝트를 패키징 하면 청크가 .pak 파일로 출력됩니다. 출력된 파일은 `Saved\StagedBuilds[PlatformName][ProjectName]\Content\Paks`의 프로젝트 폴더에 있습니다.

클릭하여 이미지 확대

App Bundle 빌드에 청크 포함하기

Play Asset Delivery의 전송 모드마다 청크를 App Bundle에 통합할 때 필요한 내용이 다릅니다.

Install-Time 에셋은 따로 변경할 필요가 없습니다.

Fast-Follow 및 On-Demand 에셋은 포함할 .pak 파일을 선택한 뒤 프로젝트의 Build/Android/gradle/assetpacks 디렉터리로 옮겨야 합니다. 전송 모드마다 다음과 같이 하위 폴더가 다릅니다.

  • Fast-Follow 에셋 팩은 반드시 `Build/Android/gradle/assetpacks/fast-follow/[assetpackname]/src/main/assets`에 있어야 합니다.

  • On-Demand 에셋 팩은 반드시 `Build/Android/gradle/assetpacks/on-demand/[assetpackname]/src/main/assets`에 있어야 합니다.

[assetpackname]을 청크를 포함할 에셋 팩 이름으로 변경합니다. .pak 파일의 구성마다 다양한 이름의 에셋 팩을 생성할 수 있지만, 에셋 팩 이름은 중복될 수 없고 Fast-Follow와 On-Demand 간에 재사용할 수 없습니다. 이 이름은 API를 사용해 에셋 팩을 쿼리할 때 사용합니다.

마지막으로는 다음 코드가 포함된 에셋 팩 폴더에 build.gradle 파일을 추가해야 합니다.

apply plugin: 'com.android.asset-pack'

def fileparts = projectDir.absolutePath.replaceAll('\\\\', '/').tokenize('/')
def assetPackName = fileparts[fileparts.size()-1]
def assetPackType = fileparts[fileparts.size()-2]

assetPack {
    packName = assetPackName
    dynamicDelivery {
        deliveryType = assetPackType
        instantDeliveryType = assetPackType
    }
}

조건을 충족한 뒤 프로젝트를 다시 App Bundle 형태로 패키징하면, 빌드에 각 에셋 팩이 포함됩니다. App Bundle을 Google Play Store에 업로드하면, Google PAD API 통해 다운로드할 수 있습니다.

이 워크플로는 언리얼 엔진 4.26에서 더 간소화될 예정입니다.

API 레퍼런스

이번에는 Google PAD 함수 라이브러리에서 사용할 수 있는 함수와 그 활용법을 자세히 다룹니다.

요청 및 오류 처리

Google PAD 함수 라이브러리의 모든 요청은 `EGooglePADErrorCode`를 반환합니다. 이 코드는 작업의 성공 여부를 나타내는데 실패 시 요청을 완료하지 못하게 하는 오류를 나타냅니다. 발생 가능한 오류 코드는 다음과 같습니다.

EGooglePADErrorCode

설명

AssetPack_NO_ERROR

요청에 발생한 오류가 없습니다. 요청한 정보를 평소대로 진행합니다.

AssetPack_APP_UNAVAILABLE

요청한 앱을 사용할 수 없습니다.

AssetPack_UNAVAILABLE

요청한 에셋 팩을 앱의 현재 버전에 사용할 수 없습니다.

AssetPack_INVALID_REQUEST

유효하지 않은 요청입니다.

AssetPack_DOWNLOAD_NOT_FOUND

요청한 다운로드를 찾지 못했습니다.

AssetPack_API_NOT_AVAILABLE

에셋 팩 API를 이용할 수 없습니다.

AssetPack_NETWORK_ERROR

시간이 초과하였거나 다른 네트워크 오류 때문에 에셋 팩의 세부 정보를 얻을 수 없습니다.

AssetPack_ACCESS_DENIED

현재 디바이스의 상황으로 인해 다운로드가 허가되지 않았습니다. 보통은 사용자가 Google 계정에 로그인하지 않아서 발생합니다.

AssetPack_INSUFFICIENT_STORAGE

저장 공간이 부족해 에셋 팩을 다운로드하지 못했습니다.

AssetPack_PLAY_STORE_NOT_FOUND

Play Store 앱이 이 디바이스에 설치되지 않았거나 공식 버전이 아닙니다.

AssetPack_NETWORK_UNRESTRICTED

`ShowCellularDataConfirmation`이 호출되었지만 와이파이를 기다리는 에셋 팩이 없을 때 반환됩니다. 사용자의 확인을 기다리지 않고 다운로드를 진행할 수 있다는 뜻입니다.

AssetPack_INTERNAL_ERROR

에셋 팩 다운로드 중에 알 수 없는 오류가 발생했습니다.

AssetPack_INITIALIZATION_NEEDED

아직 `AssetPackManager_init`를 호출하지 않아 API를 사용할 수 없습니다.

AssetPack_INITIALIZATION_FAILED

에셋 팩 API를 초기화하는 동안 오류가 있었습니다.

요청 함수는 이 반환 값 외에도 요청된 정보를 제공하는 출력 변수를 가집니다. 결과가 `AssetPack_NO_ERROR`면 제공된 정보를 가지고 정상적으로 진행할 수 있습니다. 오류가 발생했다면 흐름 제어를 통해 해당 오류 코드에 적절히 대응해야 합니다.

다운로드한 파일 위치 얻기

GetAssetPackLocation 함수는 다운로드한 에셋 팩의 위치를 가져오고 관련 정보를 로컬 캐싱합니다. 에셋을 사용할 수 있다면, 필요에 따라 캐싱된 정보를 이용할 때 사용할 정수 핸들을 출력합니다.

GetAssetsPath`를 호출하여 위치 핸들을 제공하면 원하는 에셋 팩의 에셋 경로가 포함된 스트링을 출력합니다. GetStorageMethod`는 사용자의 디바이스에 에셋 팩이 저장된 방법을 알려주는`EGooglePADStorageMethod`를 출력합니다. 에셋 경로 및 저장 방법을 알고 있다면 적절한 호출을 통해 에셋을 이용할 수 있습니다.

가능한 저장 방법은 다음과 같습니다.

EGooglePADStorageMethod

설명

AssetPack_STORAGE_FILES

에셋 팩이 개별 에셋 파일을 담은 폴더에 언패킹됩니다. 이 에셋은 표준 파일 API를 통해 액세스할 수 있습니다.

AssetPack_STORAGE_APK

에셋 팩이 패킹된 에셋 파일을 담은 APK로 설치됩니다. 이 에셋은 에셋 매니저를 통해 이용할 수 있습니다.

AssetPack_STORAGE_UNKNOWN

에셋 팩과 관련해 이용할 수 있는 정보가 없습니다. 대부분은 오류 때문에 발생합니다.

AssetPack_STORAGE_NOT_INSTALLED

에셋 팩이 설치되지 않아 이용할 수 없습니다.

위의 정보를 이용한 작업이 끝났다면, 반드시 위치 핸들을 `ReleaseAssetPackLocation`에 전달해 캐싱된 위치 정보를 해제해야 합니다.

GetAssetPackLocation`이 AsetPack_UNAVAILABLE 혹은 AssetPack_DOWNLOAD_NOT_FOUND` 오류 코드를 반환할 경우, 원하는 에셋 팩을 사용할 수 없다는 뜻이므로 다운로드해야 합니다.

에셋 팩과 관련된 정보 요청하기

RequestInfo 함수는 에셋 팩 이름의 Tarray`를 받아 현재 상태를 알려주는 EGooglePADErrorCode`를 반환합니다. RequestInfo는 다운로드에 꼭 필요한 함수는 아니지만, 원격 에셋 팩이 유효한지 여부를 결정할 때 사용할 수 있습니다.

다운로드 요청 또는 취소하기

RequestDownload 함수는 다운로드하려는 에셋 팩의 이름을 나타내는 스트링의 ‘Tarray'를 선택한 뒤, 원격 서비스에 요청을 보내 해당 에셋 팩의 다운로드를 시작합니다. `RequestDownload`에 오류가 없으면, 에셋 팩을 다운로드한 뒤 백그라운드에서 앱에 비동기적으로 전송합니다.

이 함수는 비동기적이므로 RequestDownload 함수는 다운로드한 에셋 팩에 대한 정보를 반환하지 않고, 요청의 성공 여부를 나타내는 오류 코드만 반환합니다. 현재 다운로드 상태를 점검하려면 아래 다운로드 상태 모니터링(Monitoring Download Status)에서 자세히 다룬 함수를 사용하고, 에셋 팩 자체를 활용하려면 다운로드가 끝난 뒤 `GetAssetPackLocation`을 사용해야 합니다.

CancelDownload 함수도 에셋 팩 이름 목록을 사용하고, 지정된 에셋 팩의 다운로드를 취소합니다.

무선 데이터 상태 얻기

ShowCellularDataConfirmation 함수를 사용하면 사용자가 자신의 무선 네트워크를 이용해 데이터를 다운로드할지 묻는 메시지가 나타납니다. 메시지가 이미 표시되었다면, ‘GetShowCellularDataConfirmationStatus'를 이용해 사용자의 다운로드 승인 여부를 나타내는 `EGooglePADCellularDataConfirmStatus`를 반환할 수 있습니다.

결과가 AssetPack_CONFIRM_UNKNOWN 및 `AssetPack_CONFIRM_PENDING`이라면 사용자가 아직 승인하지 않았다는 뜻이며, 애플리케이션은 사용자가 승인할 때까지 대기 상태를 유지합니다.

결과가 `AssetPack_CONFIRM_USER_CANCELLED`이면 사용자가 무선 데이터 사용을 허용하지 않기로 했다는 뜻이며, 다운로드가 허가되지 않습니다.

결과가 AssetPack_CONFIRM_USER_APPROVED`이면 사용자가 무선 데이터의 사용을 허가했다는 뜻이며, 다운로드를 진행할 수 있습니다. 이 함수가 AssetPack_NETWORK_UNRESTRICTED 결과를 포함한 EGooglePADErrorCode`를 반환하는 경우도 있습니다. 사용자가 와이파이를 사용 중이며 무선 데이터를 사용할 필요가 없다는 뜻이므로, 이 함수를 계속 점검하지 않고 다운로드를 진행할 수 있습니다.

다운로드 상태 모니터링

`GetDownloadState`를 사용하면 에셋 팩의 다운로드 상태를 로컬 캐싱하고 캐싱된 정보에 액세스를 제공하는 다운로드 핸들을 반환합니다. 이 함수는 다운로드하려는 에셋 팩의 이름을 받아 핸들을 정수 형태로 반환합니다. 다운로드 핸들을 계속 캐싱해서 다운로드 상태를 모니터링해야 합니다. 아니면 다운로드 핸들을 나중에 다시 얻어야 합니다.

유효한 다운로드 핸들이 있으면 GetDownloadStatus`를 호출해 원하는 에셋 팩의 상태를 EGooglePADDownloadStatus`로 반환할 수 있습니다. 이 열거형은 아래에서 보이는 여러 다운로드 상태 중 하나를 나타냅니다.

EGooglePADDownloadStatus

설명

AssetPack_UNKNOWN

현재 에셋 팩에 관련된 정보가 전혀 없습니다.

AssetPack_DOWNLOAD_PENDING

에셋 팩을 다운로드하라는 비동기 요청이 있었고, 현재 보류 중입니다.

AssetPack_DOWNLOADING

에셋 팩을 다운로드하고 있습니다.

AssetPack_TRANSFERRING

에셋 팩을 앱으로 전송하고 있습니다.

AssetPack_DOWNLOAD_COMPLETED

다운로드 및 전송을 모두 완료하여 에셋을 앱에 사용할 수 있습니다.

AssetPack_DOWNLOAD_FAILED

에셋 팩을 다운로드하라는 요청이 실패했습니다.

AssetPack_DOWNLOAD_CANCELED

에셋 팩을 다운로드하라는 요청이 취소됐습니다.

AssetPack_WAITING_FOR_WIFI

에셋 팩을 다운로드하기 위해 와이파이 대역폭이 확보되기를 기다리고 있습니다.

AssetPack_NOT_INSTALLED

에셋 팩이 설치되지 않았습니다.

AssetPack_INFO_FAILED

에셋 팩 정보를 요청했지만 실패했습니다.

AssetPack_REMOVAL_PENDING

에셋 팩을 제거하라는 비동기 요청이 있었고, 현재 보류 중입니다.

AssetPack_REMOVAL_FAILED

에셋 팩을 제거하라는 비동기 요청이 실패했습니다.

다운로드 상태 핸들을 사용하여 사용자의 디바이스에 현재 다운로드한 바이트 수를 반환하는 GetBytesDownloaded`와 다운로드한 총 타깃 크기를 반환하는 GetTotalBytesToDownload`를 호출할 수도 있습니다.

다운로드 상태 정보 사용이 끝났으면 `ReleaseDownloadState`를 호출해 캐싱된 다운로드 정보를 메모리에서 해제할 핸들을 준비해야 합니다.

에셋 팩 제거하기

RequestRemoval 함수를 사용하면 특정 에셋 팩의 이름을 받은 뒤, 사용자의 디바이스에서 지정한 에셋 팩을 비동기적으로 제거합니다. 에셋 팩의 제거 상태는 위에서 다룬 `GetDownloadStatus`로 모니터링할 수 있습니다.

추천하는 구현 방법

Google PAD API를 구현할 때 각 다운로드별로 다른 상태의 사이클로 모델링할 수 있습니다.

상태

설명

에셋 팩 액세스

  • `GetAssetPackLocation`으로 에셋 팩을 이미 다운로드했는지 확인합니다. 에셋의 중복 다운로드를 피하기 위해 가장 먼저 실행해야 합니다.

  • GetAssetsPath 및 `GetStorageMethod`로 파일 경로와 에셋 팩에 적합한 액세스 방식을 결정합니다.

  • `ReleaseAssetPackLocation`을 호출해 에셋 팩의 캐싱된 위치에 할당된 메모리를 해제해야 합니다.

다운로드 초기화

  • 원하는 에셋 팩을 로컬에서 사용할 수 없다면, `RequestDownload`를 호출해 다운로드를 시작합니다.

  • 연결에 문제가 있다면, 성공할 때까지 `RequestDownload`를 반복해야 할 수도 있습니다.

무선 데이터 확인 점검

  • `ShowCelllarDataConfirmation`으로 애플리케이션에 다운로드를 계속할 권한이 있는지 확인하세요.

  • 최초 무선 데이터 확인 메시지가 표시되면, GetShowCellularDataConfirmationStatus`로 메시지의 현재 상태를 출력합니다. 메시지를 취소하거나 확인할 때까지 Tick` 함수에서 계속 실행됩니다.

다운로드 상태 모니터링

  • RequestDownload`가 잘 실행되면, GetDownloadState`로 다운로드 상태를 캐싱하고 액세스에 필요한 핸들을 얻습니다. 이 함수는 한 번만 실행해야 하며, 핸들을 필요한 만큼 계속 캐싱해야 합니다.

  • GetBytesDownloaded`와 GetTotalBytesToDownload`로 다운로드 진행도를 확인합니다. `GetBytesDownloaded`는 진행도 모니터링을 그만둘 때까지 일정 간격 계속 실행되어야 합니다.

  • GetDownloadStatus`로 정확한 다운로드 상태를 확인합니다. 이 상태도 일정 간격 계속 모니터링해야 합니다. 상태가 AssetPack_DOWNLOAD_COMPLETED`로 반환되면 다운로드 상태 모니터링을 중단하고 에셋 팩에 액세스할 수 있습니다.

  • 작업을 마치면 `RelaseDownloadState`를 호출해 캐싱된 다운로드 상태에 할당된 메모리를 해제해야 합니다.

커스텀 GameState 클래스에서 솔루션을 구현하면 씬과 게임 모드를 바꾸는 도중에도 다운로드를 계속 추적할 수 있습니다. 또는, 시작 시 로드되는 프론트엔드 게임 모드에서 솔루션을 구현하여 게임을 시작하기 전 필요한 패치 및 업데이트를 수행할 수도 있습니다. 솔루션에 들어갈 정확한 세부 정보는 프로젝트에서 에셋을 업데이트할 때 필요한 내용에 따라 달라집니다.

언리얼 엔진 문서의 미래를 함께 만들어주세요! 더 나은 서비스를 제공할 수 있도록 문서 사용에 대한 피드백을 주세요.
설문조사에 참여해 주세요
건너뛰기