Unity 集成指南
环境要求
- 支持 Unity 2019.4 及以上版本
准备
- 参照 准备工作 所述创建 app,配置 app 参数
- 参照 TapSDK 快速开始 配置包名和签名
获取 SDK
Unity 2020.3.15 之前的版本为了避免后面构建报错建议升级 Gradle 版本,可参考该 Gradle 升级步骤文档。
Manifest 配置
打开项目的 AndroidManifest.xml
文件,添加如下配置:
(${applicationId} 为您的应用包名)
<activity-alias
android:name="${applicationId}.wxapi.WXPayEntryActivity"
android:exported="true"
android:targetActivity="com.taptap.payment.wechat.WechatPayActivity" />
接入外部依赖
SDK 内部使用了部分第三方库,开发者接入时需先确保 SDK 外部依赖库已正常接入,具体设置如下:
- SDK 使用的 JSON 解析库为
Newtonsoft-json
,如果当前工程已接入该依赖库,则不需额外处理,否则需在Packages/manifest.json
添加如下依赖:
"com.unity.nuget.newtonsoft-json":"3.2.1"
- SDK 使用
com.google.external-dependency-manager
管理 Android、iOS 依赖,如果当前工程已接入该依赖库,则不需额外处理,否则需在Packages/manifest.json
添加如下依赖:
{
"dependencies": {
"com.google.external-dependency-manager": "1.2.179"
},
"scopedRegistries": [
{
"name": "package.openupm.com",
"url": "https://package.openupm.com",
"scopes": [
"com.google.external-dependency-manager"
]
}
]
}
添加 SDK 依赖
SDK 支持 Unity Package Manager 及本地文件导入两种集成方式,开发者根据需求选择其中一种即可,推荐使用远程依赖。
远程依赖
SDK 支持通过 NPMJS 及 GitHub 两种方式,开发者选择其中一种即可。
1. NPMJS 接入
在项目的 Packages/manifest.json
文件中添加以下依赖:
"dependencies":{
"com.unity.purchasing":"3.1.0", //TapTap IAP 所须依赖
"com.taptap.sdk.core":"4.5.2",
"com.taptap.sdk.iap":"4.5.2",
}
但需要注意的是,需在 Packages/manifest.json
中 dependencies
同级下声明 scopedRegistries
:
"scopedRegistries":[
{
"name": "NPMJS",
"url": "https://registry.npmjs.org/",
"scopes": ["com.taptap"]
}
]
2. GitHub 接入
在项目的 Packages/manifest.json
文件中添加以下依赖:
"dependencies":{
"com.taptap.sdk.core":"https://github.com/taptap/TapSDKCore-Unity.git#4.5.2",
"com.taptap.sdk.iap":"https://github.com/taptap/TapSDKLIAP-Unity.git#4.5.2",
}
在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。
本地文件导入
在 下载页 下载下列模块对应
unitypackage
文件,并在 Unity 项目中依次通过 Assets > Import Packages > Custom Packages 进行导入,包括:TapTapSDK_Core.unitypackage
TapTapSDK 核心模块,必选。TapTapSDK_IAP.unitypackage
TapTapSDK 模块IAP,必选。
如果当前项目已集成
Newtonsoft.Json
依赖,则忽略该步骤,否则在NuGet.org
Newtonsoft.Json 页面中通过点击右侧 「Download package」 下载库文件,并将下载的文件后缀从.nupkg
修改为.zip
,同时解压该文件并复制内部的Newtonsoft.Json.dll
文件拷贝到工程Assets
的Plugins
目录下,另外为了避免导出 IL2CPP 平台时删除必要数据,需在Assets
目录下创建link.xml
文件(如果已有该文件,则添加如下内容),其内容如下:
<linker>
<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />
</assembly>
</linker>
处理安卓依赖失败
EDM4U 会自动监控 TapTap IAP 引入的 Android 依赖,但是在某些特殊情况下自动依赖解析可能失败,开发者可以通过 Assets > External Dependency Manager > Android Resolver > Force Resolve 来强制依赖解析。在测试之前请确认对于 com.taptap.android.payment:unity
的依赖被加到了 mainTemplate.gradle 文件中,如果 EDM4U 没有自动添加这个依赖,开发者也可以通过手动添加的方式处理依赖。
SDK 指南
我们在 Unity IAP 的框架下实现了一个新的商店实现,通过这种方式降低已经有 Google Play 或者 App Store 内购的 app 的接入成本。如果开发者是第一次接触到内购的流程,我们会在接下来简要说明 Unity 的内购流程,开发者也可以在 Unity 的官方文档 中了解有关内购的详细内容。
初始化 Unity Gaming Services
调用 UnityServices.InitializeAsync()
来一次性初始化 Unity Gaming Services。 这个方法会返回一个 Task
对象,开发者可以通过这个对象来获取初始化的状态信息。
using System;
using Unity.Services.Core;
using Unity.Services.Core.Environments;
using UnityEngine;
public class InitializeUnityServices : MonoBehaviour
{
public string environment = "production";
async void Start()
{
try
{
var options = new InitializationOptions()
.SetEnvironmentName(environment);
await UnityServices.InitializeAsync(options);
}
catch (Exception exception)
{
// An error occurred during services initialization.
}
}
}
初始化 IAP
确保你在初始化 IAP 的时候添加 TapPurchasingModule
,并且设置正确的 clientId
和 clientToken
。
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.Purchasing.Extension;
using TapSDK.IAP;
public class MyIAPManager : IStoreListener {
private IStoreController controller;
private IExtensionProvider extensions;
public MyIAPManager () {
var builder = ConfigurationBuilder.Instance(TapPurchasingModule.Instance);
builder.Configure<ITapTapStoreConfiguration>().SetClientId("Your Client ID Here");
builder.Configure<ITapTapStoreConfiguration>().SetClientToken("Your Client Token Here");
builder.Configure<ITapTapStoreConfiguration>().SetRegionCode(0); // 0: CN, 1: GLOBAL
builder.Configure<ITapTapStoreConfiguration>().SetEnableLog(true); // 建议在 DEBUG 过程中打开 log, Release 下关闭
builder.AddProduct("100_gold_coins", ProductType.Consumable);
UnityPurchasing.Initialize (this, builder);
}
/// <summary>
/// Called when Unity IAP is ready to make purchases.
/// </summary>
public void OnInitialized (IStoreController controller, IExtensionProvider extensions)
{
this.controller = controller;
this.extensions = extensions;
}
/// <summary>
/// Called when Unity IAP encounters an unrecoverable initialization error.
///
/// Note that this will not be called if Internet is unavailable; Unity IAP
/// will attempt initialization until it becomes available.
/// </summary>
public void OnInitializeFailed (InitializationFailureReason error)
{
}
public void OnInitializeFailed(InitializationFailureReason error, string str)
{
}
/// <summary>
/// Called when a purchase completes.
///
/// May be called at any time after OnInitialized().
/// </summary>
public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e)
{
return PurchaseProcessingResult.Complete;
}
/// <summary>
/// Called when a purchase fails.
/// </summary>
public void OnPurchaseFailed (Product i, PurchaseFailureReason p)
{
}
}
发起内购流程
在 IAP 被成功初始化以后,你可以通过调用 IStoreController.InitiatePurchase
来发起内购流程。
// Example method called when the user taps a 'buy' button
// to start the purchase process.
public void OnPurchaseClicked(string productId) {
controller.InitiatePurchase(productId, "developerPayload, e.g. user_id or order_id");
}
处理购买结果
购买完成时会调用商店监听器的 ProcessPurchase 函数。无论用户购买任何物品,您的应用程序都应该履单;例如,解锁本地内容或将购买收据发送给服务器以更新服务器端游戏模型。
此过程会返回结果以指出应用程序是否已完成对购买的处理:
结果 | 描述 |
---|---|
PurchaseProcessingResult.Complete | 应用程序已完成对购买的处理,不应再次向应用程序通知此事。 |
PurchaseProcessingResult.Pending | 应用程序仍在处理购买,除非调用 IStoreController 的 ConfirmPendingPurchase 函数,否则将在下一次应用程序启动时再次调用 ProcessPurchase 。 |
请注意,在初始化成功后,随时可能调用 ProcessPurchase
。如果应用程序在 ProcessPurchase
处理程序执行过程中崩溃,那么在 Unity IAP 下次初始化时会再次调用它,因此您可能希望实现自己的额外重复数据删除功能。
可靠性
Unity IAP 要求明确确认购买以确保在网络中断或应用程序崩溃的情况下可靠地完成购买。在应用程序离线时完成的任何购买都将在下次初始化时发送给应用程序。
立即完成购买
返回 PurchaseProcessingResult.Complete
时,Unity IAP 立即完成交易(如下图所示)。
如果您正在销售可消耗商品并从服务器履行订单(例如,在网络游戏中提供游戏币),那么您不得返回 PurchaseProcessingResult.Complete
。
否则,如果在保存到云端之前卸载应用程序,则购买的消耗品将面临丢失的风险。
将购买保存到云端
如果要将消耗品购买交易保存到云端,您必须返回 PurchaseProcessingResult.Pending
,并且仅在成功保存购买时才调用 ConfirmPendingPurchase
。
返回 Pending
时,Unity IAP 会在底层商店中保持交易为未结 (open) 状态,直至确认为已处理为止,因此确保了即使在消耗品处于此待处理状态时用户重新安装您的应用程序,消耗品购买交易也不会丢失。
调试
我们当前只提供了 Android 的库实现, 请在 Android 环境下进行各功能调试(其他平台会逐步补充完善)。