跳到主要内容
版本:v4

Unity 集成指南

环境要求​

  • 支持 Unity 2019.4 及以上版本

准备​

获取 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 的外部依赖和添加 SDK 依赖

添加外部依赖​

SDK 内部使用了部分第三方库,开发者接入时需先确保 SDK 外部依赖库已正常接入,具体设置如下:

  1. SDK 使用的 JSON 解析库为 Newtonsoft-json,如果当前工程已接入该依赖库,则不需额外处理,否则需在 Packages/manifest.json 添加如下依赖:
"com.unity.nuget.newtonsoft-json":"3.2.1"
  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.10.9",
"com.taptap.sdk.login":"4.10.9",
"com.taptap.sdk.iap":"4.10.9",
}

但需要注意的是,需在 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/tapsdk-unity-dist.git?path=/Core#4.10.9",
"com.taptap.sdk.login":"https://github.com/taptap/tapsdk-unity-dist.git?path=/Login#4.10.9",
"com.taptap.sdk.iap":"https://github.com/taptap/tapsdk-unity-dist.git?path=/IAP#4.10.9",
}

说明:自 4.7.2 起,Unity Packages 仓库已统一为大仓 tapsdk-unity-dist,所有包通过目录区分并使用 ?path= 指定子目录、# 指定版本标签。

在 Unity 顶部菜单中选择 Window > Package Manager 可查看已经安装在项目中的包。

本地文件导入​

  1. 在 下载页 下载下列模块对应 unitypackage 文件,并在 Unity 项目中依次通过 Assets > Import Packages > Custom Packages 进行导入,包括:
  • TapSDK_Core.unitypackage TapTapSDK 核心模块,必选。
  • TapSDK_Login.unitypackage TapTapSDK 登录模块,必选。
  • TapSDK_IAP.unitypackage TapTapSDK IAP 模块,必选。
  1. 如果当前项目已集成 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");
}

处理购买结果​

提示

订单超过 30 分钟未支付,订单状态会设置为「超时关闭」,该情况无回调通知。

购买完成时会调用商店监听器的 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 环境下进行各功能调试(其他平台会逐步补充完善)。