在 Unity IAP v4 或更早版本基础上接入 AppCoins
本指南介绍如何为使用 Unity IAP v4 或更早版本的 Unity 游戏接入 AppCoins Billing。AppCoins 插件需要 Unity IAP v5,因此您需要先升级。Unity IAP 从 v4 升级到 v5 会改变购买完成的处理方式,这会在接入 AppCoins 之前先影响到您的现有代码。
如果您的工程已经使用 Unity IAP v5 或更高版本,请改为参见在 Unity IAP v5 基础上接入 AppCoins。
步骤 1:将 Unity IAP 升级到 v5
打开 Window → Package Manager,找到 In App Purchasing,升级到 5.0 或更高版本。
步骤 2:应用 Unity IAP v5 的 API 变更
Unity IAP v5 以 IStoreController 上的事件订阅取代了 IStoreListener 回调接口。变化最大的是购买完成模式——ProcessPurchase 已被移除。
购买完成
变更前(v4):
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
GiveItemToUser(args.purchasedProduct.definition.id);
return PurchaseProcessingResult.Complete;
}
变更后(v5):
// Subscribe in your initialization code
_controller.OnPurchasePending += OnPurchasePending;
private void OnPurchasePending(PendingOrder order)
{
var product = order.CartOrdered.Items().FirstOrDefault()?.Product;
if (product != null) GiveItemToUser(product.definition.id);
_controller.ConfirmPurchase(order); // replaces returning PurchaseProcessingResult.Complete
}
商店初始化
变更前(v4):
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
_controller = controller;
foreach (var product in controller.products.all)
Debug.Log(product.definition.id);
}
变更后(v5):
// Subscribe before Connect()
_controller.OnProductsFetched += OnProductsFetched;
private void OnProductsFetched(List<Product> products)
{
foreach (var product in products)
Debug.Log(product.definition.id);
}
初始化失败
变更前(v4):
public void OnInitializeFailed(InitializationFailureReason error) { }
public void OnInitializeFailed(InitializationFailureReason error, string message) { }
变更后(v5):
_controller.OnStoreDisconnected += failure =>
Debug.LogError($"Store connection failed: {failure.Message}");
购买失败
变更前(v4):
public void OnPurchaseFailed(Product product, PurchaseFailureReason reason) { }
变更后(v5):
_controller.OnPurchaseFailed += OnPurchaseFailed;
private void OnPurchaseFailed(FailedOrder order)
{
Debug.LogError($"Purchase failed: {order.FailureReason}");
}
不再需要 IStoreListener
迁移到事件订阅模式之后,您的类无需再实现 IStoreListener。请移除该接口声明以及所有残留的空实现方法。
初始化商店
变更前(v4):
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
builder.AddProduct("gas", ProductType.Consumable);
UnityPurchasing.Initialize(this, builder); // synchronous, IStoreListener callback
变更后(v5):
_controller = UnityIAPServices.StoreController();
_controller.OnProductsFetched += OnProductsFetched;
_controller.OnPurchasePending += OnPurchasePending;
await _controller.Connect();
// Replaces builder.AddProduct — define product definitions and fetch after Connect
_controller.FetchProducts(new List<ProductDefinition>
{
new ProductDefinition("gas", ProductType.Consumable)
});
步骤 3:添加 AppCoins 插件
从 GitHub releases 页面 下载最新的 .unitypackage 并导入:
- 在 Unity 中依次选择 Assets → Import Package → Custom Package...
- 选择已下载的
.unitypackage文件。 - 在 Import Unity Package 对话框中确认所有项目均已选中,然后点击 Import。
插件文件将出现在 Assets/Plugins/iOS/AppCoinsSDKPlugin/ 下。
步骤 4:接入 AppCoins
当工程在 Unity IAP v5 下可以顺利编译后,接入 AppCoins 只需一行代码。请在 Connect() 调用之前添加:
using AppCoins.Unity;
// Add this before Connect()
await AppCoinsIAP.ConfigureStoreAsync(AppCoinsStoreMode.Automatic);
await _controller.Connect();
AppCoinsStoreMode.Automatic 会在符合条件的安装场景下启用 AppCoins Billing,其他情况下回落到 Apple Billing——参见运行时检测的原理。无需其他代码改动。
变更前后的完整示例
变更前 —— Unity IAP v4:
using UnityEngine;
using UnityEngine.Purchasing;
public class IAPManager : MonoBehaviour, IStoreListener
{
private IStoreController _controller;
void Start()
{
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
builder.AddProduct("gas", ProductType.Consumable);
UnityPurchasing.Initialize(this, builder);
}
public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
_controller = controller;
}
public void OnInitializeFailed(InitializationFailureReason error) { }
public void BuyProduct(string productId)
{
_controller.InitiatePurchase(productId);
}
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
GiveItemToUser(args.purchasedProduct.definition.id);
return PurchaseProcessingResult.Complete;
}
public void OnPurchaseFailed(Product product, PurchaseFailureReason reason)
{
Debug.LogError($"Purchase failed: {reason}");
}
private void GiveItemToUser(string productId)
{
Debug.Log($"Delivering: {productId}");
}
}
变更后 —— 接入 AppCoins 的 Unity IAP v5:
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Purchasing;
using AppCoins.Unity;
public class IAPManager : MonoBehaviour
{
private StoreController _controller;
private readonly List<ProductDefinition> _products = new List<ProductDefinition>
{
new ProductDefinition("gas", ProductType.Consumable)
};
private async void Start()
{
// AppCoins: configure before Connect
await AppCoinsIAP.ConfigureStoreAsync(AppCoinsStoreMode.Automatic);
_controller = UnityIAPServices.StoreController();
_controller.OnProductsFetched += OnProductsFetched;
_controller.OnPurchasePending += OnPurchasePending;
_controller.OnPurchaseFailed += OnPurchaseFailed;
// Re-fire OnPurchasePending for any unfinished purchases found by FetchPurchases()
_controller.ProcessPendingOrdersOnPurchasesFetched(true);
await _controller.Connect();
// Fetch product metadata (replaces builder.AddProduct + UnityPurchasing.Initialize)
_controller.FetchProducts(_products);
// Trigger recovery of unfinished purchases — results arrive via OnPurchasePending
_controller.FetchPurchases();
}
private void OnProductsFetched(List<Product> products)
{
foreach (var product in products)
Debug.Log($"{product.definition.id}: {product.metadata.localizedPriceString}");
}
public void BuyProduct(string productId)
{
_controller.PurchaseProduct(productId);
}
private void OnPurchasePending(PendingOrder order)
{
var product = order.CartOrdered.Items().FirstOrDefault()?.Product;
if (product == null) return;
GiveItemToUser(product.definition.id);
_controller.ConfirmPurchase(order);
}
private void OnPurchaseFailed(FailedOrder order)
{
Debug.LogError($"Purchase failed: {order.FailureReason}");
}
private void GiveItemToUser(string productId)
{
Debug.Log($"Delivering: {productId}");
}
}
从 v4 到最终结果的关键变化:
- 移除
IStoreListener——不再需要实现任何接口 UnityPurchasing.Initialize(this, builder)→await _controller.Connect()+_controller.FetchProducts(products)ProcessPurchase→OnPurchasePending+controller.ConfirmPurchase(order)OnInitialized→ 订阅OnProductsFetched事件- 在
Connect()之前新增await AppCoinsIAP.ConfigureStoreAsync(AppCoinsStoreMode.Automatic)