Google Play资产交付参考

有关Google PAD API的参考和实现指南

Windows
MacOS
Linux

Google Play Asset Delivery(Google PAD) 是Google Play商店的解决方案,用于将资产包安装到设备上后将其交付给应用程序。此解决方案设计为与 Android App Bundle 发布格式一起使用。App Bundle为最终用户发布自定义.apk,处理初始安装的代码和二进制文件,而Play Asset Delivery系统则独立于.apk提供模型、纹理、声音、着色器和其他大型资产文件。这样,通过Google Play发布的应用就可通过按需交付内容管理内容占用空间。

有关Google Play资产交付的更多详情,请参阅Android官方文档:https://android-developers.googleblog.com/2020/06/introducing-google-play-asset-delivery.html

虚幻引擎4.25 及更高版本支持通过插件集成Google PAD,使此系统易于在自己的项目中执行。此插件提供了一个函数库,用于管理下载以及从Play Asset交付系统请求信息。C++和蓝图均提供了 UGooglePADFunctionLibrary

欲了解通过Android App Bundle的更多信息,参见Android项目打包

启用Google PAD插件

可在虚幻编辑器的 插件(Plugins) 窗口的 Android 分段下找到Google PAD插件。虚幻引擎4.25.0和更高版本中默认启用该插件。如需使用Google PAD,你必须使用Android App Bundles作为你的打包格式。

Google PAD Plugin

要完全启用该插件,打开 项目设置(Project Settings) 并导航至 插件(Plugins) > GooglePAD > 打包(Packaging)。单击 启用插件(Enable Plugin) 复选框,该模块将在Android项目启动时可用。

Google PAD Plugin Options

若要将Google PAD用于 安装时(install-time) 资产,则还需导航至 平台(Platforms) > Android > APK打包(APK Packaging),并禁用 在APK内打包数据(Package data inside APK)。main .obb文件然后会作为安装时资产包自动交付。

点击查看大图

创建资产包

Google PAD的 资产包 封装在Android App Bundle构建中,并在上传时由Google Play商店管理。本部分介绍如何打包和整理资产包,以便包含在App Bundle中。

资产包交付模式

数据块(Chunks) 是虚幻引擎用于整理外部资产的格式。数据块0(Chunks 0)代表游戏的基础安装,而所有其他数据块都是.pak文件,其中包含游戏主安装之外的资产。

要使用Google PAD,你必须将游戏的资产分组为数据块,然后根据你要使用的交付模式将这些数据块分组为资产包。Google Play Asset Delivery支持以下资产包交付模式:

交付模式

文件大小限制(每个资产包)

说明

安装时间(Install-Time)

1 GB

安装时交付的资产包。项目中的主要.obb会自动捆绑到此资产包中。

快速跟进(Fast-Follow)

512 MB

应用程序安装后,资产包自动下载。无需打开应用程序即可下载。每个项目仅允许使用一个快速跟进资产包。

按需(On-Demand)

512 MB

应用程序运行时下载的资产包。

你总共可以为每个应用程序创建 50 个资产包。每个项目仅有一个安装时间和一个快速跟进资产包,但是只要不超过此限制,你就可以使用任意数量的按需资产包。

创建数据块

打开 **项目设置,然后导航到项目(Project)> 打包(Packaging),并确保启用生成块(Generate Chunks)。

Activate Generate Chunks in the Project > Packaging section

现在,你可以使用 资产管理器主要资产标签 将资产整理为数据块。

在内容浏览器中点击右键,然后点击 其他(Miscellaneous) > 数据资产(Data Asset),即可创建主要资产标签。

点击查看大图。

系统将提示你选择 数据资产类别(Data Asset Class)。选择 主资产标签(PrimaryAssetLabel),然后点击 选择(Select)

点击查看大图。

命名新的主资产标签,然后双击编辑其信息。

点击查看大图。

启用 我的目录中的标签资产(Label Assets in my Directory),将同一文件夹中的所有资产指定为属于此资产标签。将 数据块ID(Chunk ID) 设置为大于0的任何值,以便指定属于此标签的资产属于哪个数据块。你也可以使用 显式资产(Explicit Assets) 列表将资产直接添加到资产标签。

资产管理器位于 项目设置(Project Settings) 中的 游戏(Game) > 资产管理器(Asset Manager)

点击查看大图。

在这里,你可以指定项目将使用的规则,以便程序化地将资产分组为数据块。有关更多细节,请查阅烘焙和数据块划分 页面。

指定哪些资产属于特定数据块后,则 打包 项目会将数据块输出为 .pak 文件。你可以在 Saved\StagedBuilds[PlatformName][ProjectName]\Content\Paks 的项目文件夹中找到文件。

点击查看大图。

在App Bundle构建中包含数据块

对于将数据块合并到App Bundle中时,Play Asset Deliver的每种交付模式都有不同的要求。

对于安装时间资产,你无需进行任何更改。

对于快速跟进(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文件集创建多个不同的命名资产包。但是,资产包的名称必须唯一,并且不能在快速跟进和按需之间重复使用。该名称将是你在使用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商店时,将可以使用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,但没有资产包正在等待wi-fi,则返回此代码。这意味着下载可继续进行,无需等待用户确认。

AssetPack_INTERNAL_ERROR

下载资产包时出现未知错误。

AssetPack_INITIALIZATION_NEEDED

尚未调用 AssetPackManager_init,因此尚未启用该API。

AssetPack_INITIALIZATION_FAILED

初始化资产包API时出错。

除了此返回值之外,请求函数还具有提供所请求信息的out变量。若获取的结果为 AssetPack_NO_ERROR,则可正常处理所提供信息。否则,应使用流控制适当响应提供的错误代码。

获取已下载文件的位置

GetAssetPackLocation 函数获取已下载资产包的位置,并在本地缓存相关信息。若资产可用,将输出整数句柄,该句柄可用于按需访问缓存信息。

调用 GetAssetsPath 并提供位置句柄,将输出带有所需资产包资产路径的字符串。GetStorageMethod 将输出 EGooglePADStorageMethod,指示资产包存储在用户设备上的方式。了解资产路径和存储方法后,就可使用适当的调用访问资产。

可用的存储方式如下:

EGooglePADStorageMethod

说明

AssetPack_STORAGE_FILES

资产包解压缩到包含各资产文件的文件夹。可通过标准文件API访问此类资产。

AssetPack_STORAGE_APK

资产包作为APK安装,其中包含已打包的资产文件。可通过AssetManager访问此类资产。

AssetPack_STORAGE_UNKNOWN

没有关于资产包的可用信息,很可能是由于出现错误。

AssetPack_STORAGE_NOT_INSTALLED

资产包未安装,因此不可用。

使用以上信息完成操作后,必须将位置句柄传递给 ReleaseAssetPackLocation,释放缓存位置信息。

GetAssetPackLocation 返回 AsetPack_UNAVAILABLE 或 AssetPack_DOWNLOAD_NOT_FOUND 的错误代码,则所需资产包不可用,必须下载。

请求关于资产包的信息

函数 RequestInfo 接收资产包名称的 Tarray,并返回指示当前状态的 EGooglePADErrorCode。无需RequestInfo启动下载,但RequestInfo可用于确定远程资产包是否有效。

请求或取消下载

函数 RequestDownload 接收字符串的 Tarray,该字符串表示要下载的资产包的名称,然后向远程服务发送请求以开始下载资产包。若 RequestDownload 没有显示错误,则资产包将在后台下载并异步传输到应用程序。

由于此功能异步,因此 RequestDownload 函数不会返回有关已下载资产包的信息,只有表示请求是否成功的错误代码。必须使用下面监视下载状态 部分中详细介绍的函数检查下载的当前状态。要访问资产包本身,必须在下载完成后使用 GetAssetPackLocation

函数 CancelDownload 也使用资产包名称列表,并将取消下载指定的资产包。

获取蜂窝数据状态

函数 ShowCellularDataConfirmation 将提示用户是否要使用蜂窝网络下载数据。若提示已存在,则可使用GetShowCellularDataConfirmationStatus返回 EGooglePADCellularDataConfirmStatus,指示用户是否已批准下载。

结果为 AssetPack_CONFIRM_UNKNOWNAssetPack_CONFIRM_PENDING 表示用户尚未获得批准,申请在获得批准前待定。

结果为 AssetPack_CONFIRM_USER_CANCELLED 表示用户已选择不允许使用蜂窝数据,此时不允许下载。

结果为 AssetPack_CONFIRM_USER_APPROVED 表示用户已明确同意使用蜂窝数据,将允许下载继续。此外,若此函数返回结果为 AssetPack_NETWORK_UNRESTRICTEDEGooglePADErrorCode,则该用户已连接wi-fi网络,无需使用蜂窝网络数据,因此将允许下载,而无需继续查看此函数。

监测下载状态

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

资产包下载正等待wi-fi带宽继续。

AssetPack_NOT_INSTALLED

当前未安装资产包。

AssetPack_INFO_FAILED

请求有关资产包的信息失败。

AssetPack_REMOVAL_PENDING

已提出删除资产包的异步请求,该请求当前正在待处理中。

AssetPack_REMOVAL_FAILED

删除资产包的异步请求失败。

还可使用下载状态句柄调用 GetBytesDownloaded(返回当前下载到用户设备的字节数)和 GetTotalBytesToDownload(返回下载的总目标大小)。

使用下载状态信息完成后,必须调用 ReleaseDownloadState 并提供句柄,从内存释放缓存的下载信息。

删除资产包

函数 RequestRemoval 接收资产包名称,并以异步方式从用户设备删除指定资产包。如上所述,可使用 GetDownloadStatus 监视资产包的删除状态。

推荐的实现

Google PAD API的实现可以建模成不同状态的循环,每个状态对应一个下载。

状态

说明

正在访问资产包(Accessing Asset Pack)

  • 使用 GetAssetPackLocation 检查是否已经下载资产包。应先运行此函数,避免尝试下载已有资产。

  • 使用 GetAssetsPathGetStorageMethod 确定适用于资产包的文件路径和访问方法。

  • 必须调用 ReleaseAssetPackLocation 为资产包的缓存位置释放内存。

正在启动下载(Initiating Download)

  • 若所需资产包在本地不可用,请调用 RequestDownload 启动下载。

  • 若出现连接问题,则可能需要重复执行 RequestDownload 直到成功。

正在检查蜂窝数据确认(Checking for Cellular Data Confirmation)

  • 使用 ShowCelllarDataConfirmation 确保应用程序具有继续下载的权限。

  • 在出现初始蜂窝数据确认提示后,使用 GetShowCellularDataConfirmationStatus 输出提示的当前状态。这将在 Tick 函数中持续出现,直到取消或确认提示。

正在监视下载状态(Monitoring Download Status)

  • RequestDownload 成功运行后,使用 GetDownloadState 缓存下载状态并获取句柄访问。此函数仅需调用一次,只要你需要使用它,就请缓存该句柄。

  • 使用 GetBytesDownloadedGetTotalBytesToDownload 查看下载进度。GetBytesDownloaded 将在标记后持续运行,直到停止监视进度为止。

  • 使用 GetDownloadStatus 确定具体的下载状态。此外,它还应该在Tick中持续被监测。状态返回 AssetPack_DOWNLOAD_COMPLETED 时,你可以停止监测下载状态并访问资产包。

  • 完成后,必须调用 RelaseDownloadState 释放用于缓存下载状态的内存。

在自定义 GameState 类中执行解决方案即可连续跟踪下载,即使更改场景和游戏模式也是如此。或者,可能想要在启动时加载的前端游戏模式中执行解决方案,以便在启动游戏之前执行必要的补丁程序和更新。解决方案的具体细节将取决于项目具体的资产更新需求。

Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback