Unity IAP 为中国境外的开发者提供了一个在中国市场发布应用程序的方便渠道。本指南将介绍 Unity Channel SDK,并描述开发者将 IAP 内容发布到 Xiaomi Mi Game Center 平台的端到端过程。
将游戏发布到 Mi Game Center 的过程分为三个步骤:
Mi Game Center 是小米的官方 Android 应用商店。用户在此商店中可以搜索、浏览和使用安全支付方法购买小米平台的商品。有关更多信息,请访问 Unity 的小米合作伙伴站点。
Unity Channel 是 Unity IAP 的一个内部组件,通过简化用户登录、支付管理以及中国政府应用程序分发监管审批过程,帮助中国境外的开发者访问中国应用商店市场。
由于采用了 Unity Channel,Mi Pay(小米支付)的集成过程与 Google Play 及 iTunes 在以下方面存在不同:
本部分介绍通过 Unity Editor 使用 Unity IAP SDK 配置游戏的过程:
小米仅支持 Android 平台的发布。针对 Android 进行项目配置的过程分为 4 步。
在 Editor 的 Services 窗口中启用 Unity IAP(__Window__ > General > __Services__;请参阅有关设置 Unity IAP 的文档)。在提示导入 IAP 资源包时,务必选择 Import(请参阅下图)。从版本 1.13.0 起,Unity IAP 资源包中包含 Unity Channel 和小米 SDK。
如果希望在不采用应用内购 (IAP) 的情况下将应用程序发布到 Mi Game Center,请从 Build Settings 窗口 (File > Build Settings) 中安装小米 Unity Channel 独立 SDK,具体操作是从 Platform 菜单中选择 Android__,然后从出现的 Xiaomi Game Center__ 菜单选项中选择 Add。
Unity Channel 包含一个资源,该资源提供用于管理应用商店凭据和测试模式功能的 Editor 界面。导入 Unity IAP 资源包时,此 AppStoreSettings 资源会安装到 Assets/Plugins/UnityChannel/XiaomiSupport/Resources 中。此外还可在 Editor 中通过选择 Assets > Create > App Store Settings 来手动创建该资源。选择该资源并查看 Inspector 即可访问这一界面。
注意:__AppStoreSettings__ 资源仅在 Unity 5.6 以上版本中可用。
为了进行通信,Unity 和小米服务器都要求您提供游戏的唯一标识符。请注意,您可以在此处通过将项目 ID 粘贴到搜索字段来检索您的 Unity 客户端凭据。Unity 5.3 或 5.4 用户必须以这种方式检索和设置凭据,因为他们不能访问 AppStoreSettings 资源。上图中显示的设置如下所述:
在集成过程的各个位置需要用到这些凭据和测试模式切换开关。请注意,应用商店设置数据会在服务器端更新,而不是保存到客户端。
如果已启用 Unity IAP 来导入小米资源包,则不需要采取任何操作。否则,请参阅有关设置 Unity IAP 的文档以启用该服务。
此外还可以通过 Unity Asset Store 安装最新的 Unity IAP 插件。
Unity IAP 中内置的小米客户端 SDK 取决于客户端中可用的商品元数据。因此,必须通过 Editor 的 IAP Catalog GUI (Window > Unity IAP > IAP Catalog) 来定义商品。
填充目录: IAP Catalog GUI 定义了商品及其在游戏客户端运行时的元数据。有关 Codeless IAP 的文档包含了有关通过 IAP Catalog 进行商品配置的信息。小米平台需要特别注意以下商品属性:
有关商品属性及其参数的更多信息,请参阅有关定义商品的文档。
在 Editor 的 IAP Catalog 窗口中,通过选择 App Store Export > Xiaomi Mi Pay Catalog 来导出目录。
将 MiGameProductCatalog.prop 文件导出到所选的位置。将商品目录导入到 Xiaomi Developer Portal 上,具体操作是导航至项目的 IAP Configuration 选项卡,然后选择 __Import__(请参阅下面有关导入 IAP 商品目录的部分)。
导出 IAP Catalog 还会将 MiGameProductCatalog.prop 文件的副本写入到项目的 Assets/Plugins/Android/assets/ 目录(请参阅下图)。Unity IAP 在 IAP Catalog 编辑器中以及在运行时使用此文件。如果未通过 Xiaomi Developer Portal 显式导入任何目录文件,则此目录还会用作应用程序的默认商品目录。
Unity IAP 通常需要一个配置构建器(此构建器使用要为目标应用商店解析的 IAP Catalog 数据),随后需要 Unity IAP Initialize()
API(请参阅有关初始化 IAP 的文档)。
小米游戏在初始化 IAP 之前需要一个额外步骤,因为 Mi Game Center 要求应用程序在启动时通过登录 API 共享其凭据。
修改后的初始化过程变为:
initialize()
API。应在游戏的运行时生命周期中尽早(最好在启动时)执行这些步骤。您可以在同一脚本中实现它们。
以下示例说明如何使用 Unity Channel SDK 修改初始化以便调用登录 API:
using AppStoreSupport;
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Store;
// 在游戏启动时运行一次脚本。
public class UnityChannelSample : MonoBehaviour
{
// 小米登录需要一个登录监听器。
//通过实现 Unity Channel SDK 中包含的 ILoginListener 抽象类来创建一个登录监听器。
class SampleLoginListener : ILoginListener
{
public Action initializeIAP;
//步骤 1 成功;调用步骤 2
public void OnInitialized()
{
Debug.Log("Initialization succeeded.");
UnityEngine.Store.StoreService.Login(this); // 如果初始化成功,则启动小米登录
}
// 步骤 1 失败;显示错误消息和帮助
public void OnInitializeFailed(string message)
{
Debug.Log("Initialization failed.");
}
// 步骤 2 完成;调用步骤 3
public void OnLogin(UserInfo userInfo)
{
Debug.Log(string.Format("Login successful: userId {0}, userLoginToken {1}, channel {2}", userInfo.userId, userInfo.userLoginToken, userInfo.channel));
// 登录成功时,继续初始化 IAP
initializeIAP();
}
// 步骤 2 失败;显示错误消息和帮助
public void OnLoginFailed(string message)
{
Debug.Log("Login failed.");
}
}
}
注意:必须使用上述示例代码中的所有函数,这些函数涵盖了登录过程的所有可能步骤。但是,您可以选择每个函数内调用的操作。在该示例中,调试文本取代了调用的操作。该示例中的 OnLogin() 方法用于启动 Unity IAP 初始化函数。
接下来,使用登录监听器以及存储在 AppStoreSettings 资源中的应用程序凭据来初始化小米 API:
void Awake()
{
// 根据 SamleLoginListener 类创建一个登录监听器
SampleLoginListener loginListener = new SampleLoginListener();
// 将 initializeIAP 操作(来自 SampleLoginListener 类)关联到一个函数(在下一步中定义)
loginListener.initializeIAP = ConfigureIAP;
// 访问 AppStoreSettings 资源以使用存储的凭据生成 AppInfo。AppStoreSettings 类属于 AppStoreSupport 库的一部分。
AppStoreSettings appStoreSettings = Resources.Load<AppStoreSettings>("AppStoreSettings");
// 使用凭据和登录监听器来初始化小米
UnityEngine.Store.StoreService.Initialize(appStoreSettings.getAppInfo(), loginListener);
}
在加载项目的 AppStoreSettings 资源时,getAppInfo()
函数将返回用于 Mi Game Center 商店初始化过程的凭据数据。
最后,使用配置构建器为小米转换 IAP Catalog 中的商品数据,然后初始化 Unity IAP:
// 配置构建器需要一个商店监听器。
// 通过实现 IStoreListener 抽象类来创建一个商店监听器。
class StoreListener : IStoreListener
{
private IStoreController controller;
private IExtensionProvider extensions;
// 当 Unity IAP 准备好进行购买时调用。
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
this.controller = controller;
this.extensions = extensions;
}
//请注意,如果互联网不可用,则不会调用此项;
// Unity IAP 会在互联网变为可用状态后尝试进行初始化。
public void OnInitializeFailed(InitializationFailureReason error)
{
}
//购买完成时或 Unity IAP 遇到不可恢复的初始化错误时调用;
// 可能在 OnInitialized() 之后的任何时间调用。
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e)
{
return PurchaseProcessingResult.Complete;
}
//购买失败时调用。
public void OnPurchaseFailed(Product i, PurchaseFailureReason p)
{
}
}
//运行配置构建器以定义商品
public void ConfigureIAP()
{
// 加载来自 IAP Catalog 中的商品
var module = StandardPurchasingModule.Instance();
var builder = ConfigurationBuilder.Instance(module);
var catalog = ProductCatalog.LoadDefaultCatalog();
// 对目录中的商品循环操作,将元数据提取到构建器
foreach (var product in catalog.allProducts)
{
if (product.allStoreIDs.Count > 0)
{
var ids = new IDs();
foreach (var storeID in product.allStoreIDs)
{
ids.Add(storeID.id, storeID.store);
}
builder.AddProduct(product.id, product.type, ids);
}
else
{
builder.AddProduct(product.id, product.type);
}
}
// 根据 StoreListener 类创建商店监听器
StoreListener storeListener = new StoreListener();
// 初始化 Unity IAP
UnityPurchasing.Initialize(storeListener, builder);
}
配置构建器引用商品 ID (Product IDs) 和商品类型 (Product Types) 来自动填充价格 (Price)、类型 (Type)、名称 (Title) 和描述 (Description) 元数据。它会使用 IAP Catalog 的 IAPProductCatalog.json 文件以及 Unity IAP 初始化过程中实例化的 builder
对象。
有关游戏内购买实现方法的信息,请参阅以下相关文档:
通过在 AppStoreSettings 资源界面中切换测试模式,在非小米 Android 设备上测试游戏的购买流程。Unity Channel 还提供了一个用于切换测试模式的 API:
AppInfo.debug = true;
Unity Channel 包装器包含 AppInfo
类,并将数据传递给小米 SDK。要将应用程序提交给小米,必须启用测试模式。测试模式也会出于测试目的而绕过信用卡要求。启用测试模式后,应编译项目并从 Android 设备启动生成的 APK 文件。
要测试实际购买情况,请将测试模式设置为 false 并在小米设备上进行测试。请注意,实际购买时要求具有 Xiaomi Mi Pay 帐户和适当的货币(如人民币)。
本部分介绍通过 Unity Editor 使用 Unity IAP SDK 提交游戏的过程:
在 Unity Editor 中,通过选择 Window > Unity IAP > Android > Target Xiaomi Mi Game Pay 将 Unity IAP 目标设置为 Mi Game Pay。这样可以让小米成为游戏 APK 的下一次发布目标平台。此外还会创建配置文件以便在运行时通知 Unity IAP 使用 Xiaomi Mi Pay 原生计费 API。
在推送到小米之前,应对游戏进行试编译:在本地进行编译或者在 Unity Cloud Build 中将项目配置为 Android 编译目标后再进行编译(请参阅有关 Cloud Build 的文档)。
在 Editor 中通过 Unity Services 窗口启用 Cloud Build(请参阅有关 Cloud Build 实现的文档)。
使用以下两种方法之一将编译文件上传到项目的编译历史记录:
通过 Editor:
通过 Unity Cloud Build 开发者控制面板 (Developer Dashboard):
使用以下两种方法之一将托管的编译文件推送到 Xiaomi Developer Portal:
通过 Editor:
在 Cloud Build Services 窗口中,根据编译历史记录时间轴找到所需的编译文件,然后选择 Push to Xiaomi。确认想要推送,然后确认操作完成。
通过 Unity Cloud Build 开发者控制面板 (Developer Dashboard):
注意:只有项目所在组织的所有者才能将项目部署到小米。
您的 UDN 凭据可授权访问在 Xiaomi Unity Developer Portal 中上传的项目。首次登录时,必须先确认小米的条款和条件,然后再继续进入 Projects 列表。找到想要提交的项目。该项目的状态(下面突出显示处)最初显示为 Version1.0: Draft。选择剪贴板图标可查看项目全程状态变化的提交日志。选择状态链接可展开项目的元数据详细信息。
下图显示了详细信息:
本部分包含要在 Mi Game Center 显示的文本。
本部分包含在 Mi Game Center 显示的适用于手机和平板电脑设备的营销资源。请注意以下原则:
准备好后,请选择 Submit 以将游戏提交给小米供审查。项目的状态标识变为 In review。当项目处于审查状态时,无法编辑其详细信息。展开项目再选择 Cancel 即可取消审查并修改项目的详细信息。
您需要有 ISBN 出版许可证才能发布应用程序。小米为您通过中国国家新闻出版广电总局 (SAPPRFT) 的 ISBN 审批流程提供全面的支持。
小米不保证 SAPPRFT 会批准所有游戏(请参阅 SAPPRFT 提交指南)。为了满足应用商店和国家合规规则,您可能需要对游戏进行一些更改。
提交中国政府审批时,请注意以下提示:
在完成提交之前,请按照以下步骤确保小米拥有最新的 IAP 商品目录:
当小米表示批准时,项目状态将变为 Approved 并收到以下凭据:
在 AppStoreSettings 资源或初始化脚本中输入这些凭据值,然后将测试模式设置为 false
。创建新的游戏编译文件,然后像之前一样将此编译文件推送到小米。
小米通过电子邮件提供一份开发者合同。一旦您签订合同,小米便会推动政府审批程序。当游戏收到 ISBN 许可证并获准发布到 Mi Game Center 时,小米会通知您。
小米的内容审查过程通常需要 1–2 个工作日(除非小米建议更改游戏内容)。不过,政府审批程序和许可证分发过程可能需要 4–8 个月的时间。有关审查过程的更多信息,请参阅 Unity-Xiaomi 合作伙伴页面的常见问题解答 (FAQ) 部分。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.