Unlock in-game content with StoreKit and Background Assets
App Store & Distribution 进阶 9m

通过 StoreKit 和后台资源解锁游戏内内容

Unlock in-game content with StoreKit and Background Assets

2026年6月9日

在 Apple 官方观看视频

一句话判断

✅ Apple 官方下场帮 Unity 开发者把 Steam 资产和 IAP 无缝搬到 Apple 平台了,这是明抢 PC 游戏开发者。

这场 Session 讲了什么

这场 Session 最值得关注的一件事是:Apple 官方下场帮 Unity 开发者把 Steam 资产和 IAP 无缝搬到 Apple 平台了。过去 Unity 游戏移植到 Mac 或 iPad,最头疼的就是几十 GB 的多语言资源包怎么按需下载,以及 StoreKit 的 C# 桥接怎么写。现在 Apple 直接把 Background Assets (后台资源) 的 Apple-Hosted 额度拉到了 200GB,还加了 Localized asset packs (本地化资源包) 自动按系统语言下发。

更绝的是,他们搞了个 Steam Asset Converter,用 xcrun ba-package convert 一行命令就能把 Steam 的 depot 转成 Apple 的 asset pack。配合新出的 StoreKit 和 Background Assets Unity 插件,PC 游戏移植到 Apple 平台的工程阻力被大幅削弱。这对做跨平台游戏的团队来说,能省下至少几个月的基建时间。

值得深挖的点

Steam Depot 一键转换与 200GB 托管额度

Apple 想要 3A 和大型独立游戏,但以前开发者自己搞 CDN 或者分包太痛苦,移植成本极高。现在 Apple 提供单 App 200GB 的免费托管额度,加上 xcrun ba-package 命令行工具,直接复用 Steam 现有的构建管线。你不需要重写打包脚本,只要把 Steam 的 .vdf 文件喂给转换器,就能生成 Apple 的 .aar 归档。

这个设计的 trade-off 很明显:强绑定 Apple 生态和 Xcode 27 工具链,但省去了巨大的基建和带宽成本。对于中小团队来说,这简直是白嫖的基础设施。你甚至可以在 CI/CD 里加一步,让 macOS 构建机自动把 Steam 资产转成 Apple 格式并上传到 App Store Connect。

Localized Asset Packs 与 Unity C# 插件

多语言语音和高清贴图是游戏体积膨胀的元凶。以前靠自己在 C# 里写语言判断和下载逻辑,还要处理断点续传,现在系统级接管了。结合新发布的 Unity 插件,开发者可以直接用 AssetPackManager.GetManifestAsync() 拿清单,用 DownloadStatusUpdatesAsync 监听进度。

坑点在于系统的 fallback 逻辑:如果玩家选了 en-GB 但你只提供了 en-US,系统会自动回退,但这要求你在 manifest JSON 里严格配好 language 标签。如果标签写错或者没配主语言,系统会直接下载所有语言包,导致体积爆炸。一定要在 Xcode 的 Mock Server 里把各种语言回退路径测一遍。

代码片段

1. 转换 Steam 仓库为 Apple 资源包

场景:在 CI/CD 或本地终端,把现有的 Steam 构建配置直接转成 Apple 需要的 manifest 和归档文件。

# 将 Steam depot 转换为 asset pack manifest
xcrun ba-package convert --asset-pack-id voice-english --l en-US --on-demand voice-english.vdf -o voice-english.json

# 将 manifest 打包成 .aar 归档文件
xcrun ba-package voice-english.json -o voice-english.aar

坑:这个工具目前只在 macOS (Xcode 27) 上可用,Linux 和 Windows 版本还在“即将推出”的状态,跨平台 CI 节点需要专门配一台 Mac。

2. Unity 中处理 StoreKit 购买与验证

场景:使用官方 C# 插件发起购买,并正确处理交易验证和状态完结。

// 使用 StoreKit 插件获取并购买商品
using Apple.StoreKit;

async void Purchase(Product product) {
    var result = await product.Purchase();
    
    // 检查购买结果和交易验证
    if (result.Result == PurchaseResult.ResultEnum.Success
        && result.TransactionVerification.IsVerified)
    {
        // 解锁已购买的内容并完结交易
        result.TransactionVerification.SafePayload.Finish();
    }
}

坑:必须调用 Finish() 来完结交易,否则系统会认为交易挂起,下次启动时 Transaction.Updates 还会重复派发这个事件。

3. Unity 中按需下载本地化资源包

场景:玩家进入特定关卡前,按需拉取对应语言的资源包并更新 UI 进度条。

// 使用 Background Assets 插件按需下载资源包
using Apple.BackgroundAssets;

async void LoadTutorial(string language) {
    string assetPackId = $"tutorial-{language}";
    
    // 获取资源清单
    AssetPackManifest manifest = await AssetPackManager.GetManifestAsync();
    AssetPack assetPack = manifest.GetAssetPack(assetPackId);
    
    // 监听下载进度并更新 UI
    await foreach (var statusUpdate in AssetPackManager.DownloadStatusUpdatesAsync(assetPack)) {
        UpdateProgressBar(statusUpdate.Progress);
    }
}

坑:DownloadStatusUpdatesAsync 是个异步流,记得在关卡卸载或玩家取消时传入 CancellationToken,否则会导致内存泄漏和后台无效下载。

最佳实践

  • 老项目迁移:别急着全量重构。先接入 StoreKit Unity 插件替换掉现有的第三方 IAP 桥接,跑通 Transaction.Updates 监听。资源包方面,挑体积最大的多语言语音包,用 xcrun ba-package 转成 Localized asset packs (本地化资源包) 试水。
  • 新项目架构:直接白嫖 Apple-Hosted 的 200GB 额度,别自己花钱搞 CDN 和分包下载逻辑了。把构建管线和 Steam 对齐,一套 depot 配置两端打包。
  • 避坑指南Transaction.Updates 必须在游戏启动最早期就注册监听,否则会漏掉后台完成的交易。Localized asset packs 的 fallback 机制依赖 manifest 里的 language 标签,配错了会导致玩家下错资源。

还有什么值得关注

  • 横屏支付 UI:系统支付 Sheet 在横屏模式下重新设计了 UI,不再粗暴遮挡游戏画面。
  • 本地 Mock 调试:Xcode 27 内置了 Background Assets Mock Server,本地调试按需下载不用再连真机沙盒环境。
  • 商店视觉升级:App Store 和 Apple Games app 的搜索结果现在支持直接展示游戏视频和新的视觉 Header。
StoreKit Background Assets Unity Steam App Store