加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

unity学习—Unity IAP赚取你的第一桶金

(2017-04-18 23:10:59)
最近接触了一下unity官方自带的IAP支付功能,这里记录一下学习过程。
参考链接:
http://www.manew.com/thread-100403-1-1.html
https://unity3d.com/cn/learn/tutorials/topics/ads-analytics/integrating-unity-iap-your-game

前期准备,你需要在asset store 上面下载unity IAP插件,免费的,官方出品。
下完之后导入到unity内。如图所示:
http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/OoG8aNCp4XjMSPMBXohXk33YIzQpGcT8iF7iZTZ9UdA!/o/dGkBAAAAAAAA&ek=1&kp=1&pt=0&bo=wwDKAMMAygADEDU!&su=1225628465&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />

然后在unity内打开services Tab。

http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/JOMko5sTX39vSlfeQ*i01b.4WOVlwo6kmXosEK5d1IA!/o/dGkBAAAAAAAA&ek=1&kp=1&pt=0&bo=JQFBAyUBQQMDEDU!&su=1236750097&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />                http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/k5V7v*o9.fVeK87cHRmm.sx8lGyOoe5s8i9fXpgKWg8!/o/dGkBAAAAAAAA&ek=1&kp=1&pt=0&bo=HwFeAh8BXgIDEDU!&su=1168344081&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />


当然你打开的Tab面板上Analytics和In-App Purchasing 是OFF的,如果我们想要使用官方的IAP,我们需要把分析和购买启动。
也就是Analytics和In-App Purchasing启动。
在启动In-App Purchasing的时候,会有一个什么13岁的购买规则之类的,不用管它,直接Enable就可以了。
上图右边的图片就是启动In-App Purchasing之后的样子。
官方规定启动In-App Purchasing,必须启动分析。

如果你们是一个团队进行配合工作,那么这个unity工程账号可能就要使用公司的账号了。
这个时候,我们可以选择下图红色框选中的setting进行工程与团队的选择。

http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/DLZP7li*CASM5wAA4dOvmXhzZLeQz7Ko4Ekkxx*myzg!/o/dGkBAAAAAAAA&ek=1&kp=1&pt=0&bo=NwGZADcBmQADEDU!&su=1261214129&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />

因为我开的是一个测试工程,所以就用的我自己的账号。
如果是团队合作的话,下图中的那个ID,一定得是一样的。

http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/9EkuwzGbOxOW*66u2la*ZVELCw3q0bR1*7O3Fw916Sc!/o/dGgBAAAAAAAA&ek=1&kp=1&pt=0&bo=NwE1ATcBNQEDEDU!&su=1178974561&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />


OK,unity中的前期配置就是这样。

如果你是想要IOS版本的IAP,你需要在Apple Developer 和 iTunes上面进行配置。
具体流程:https://docs.unity3d.com/Manual/UnityIAPAppleConfiguration.html
如果你是想要GooglePlay的IAP,你需要在GooglePlay上面进行一些配置。
具体流程:https://docs.unity3d.com/Manual/UnityIAPGoogleConfiguration.html

当然现在unity 官方的IAP还支持一些平台,比如Windows store ,Mac store等等。

注意:如果你在这些支付平台上没有配置成功的话,游戏内部的购买是不会成功的。
所以一定要在这些平台上配置成功(PS:辛酸泪啊,就是这个搞了我好多天,我一直在检查代码,可就是没有发现代码的错误,后来才知道是平台配置完全就是错的,怪不得一直无法连接。果然还是 too young too simple啊)

如果上述的那些你都以及完成了,那么你可以在官网中找到下面这个代码,直接粘贴复制。
网址传送门:https://unity3d.com/cn/learn/tutorials/topics/ads-analytics/integrating-unity-iap-your-game
http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/vVl1E.kgbTO4xGrZDnDuN04Fct2z*gqnEwdEWbzHSfQ!/o/dGgBAAAAAAAA&ek=1&kp=1&pt=0&bo=ZASRAWQEkQEDEDU!&su=1180294353&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />
 
 
这是官方给的一个例子,我们在这个基础上进行修改。

首先,我们先定义一些我们需要让玩家购买的产品的ID,这个要与你在IOS或者GooglePlay上的配置保持相同。
这里,我就随便写了。以IOS IAP为基准。
public static string consumableOne = "com.usegame.one.50rmb";
public static string consumableTwo = "com.usegame.two.100rmb";
public static string consumableThree = "com.usegame.three.150rmb";
 我定义了三种产品的ID。

然后是初始化。
我是在Awake中进行的。
 
    void Awake() {
        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
        builder.AddProduct(consumableOne, ProductType.Consumable, new IDs() {
            {consumableOne,AppleAppStore.Name },//
            //GooglePlay:
            //{consumableOne,GooglePlay.Name },
        });
        builder.AddProduct(consumableTwo, ProductType.Consumable, new IDs() {
            {consumableTwo,AppleAppStore.Name },
        });
        builder.AddProduct(consumableThree, ProductType.Consumable, new IDs() {
            {consumableThree,AppleAppStore.Name },
        });
        UnityPurchasing.Initialize(this, builder);
    }
 
 然后就是我们的购买函数了:
    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) {
        if (String.Equals(args.purchasedProduct.definition.id, consumableOne, StringComparison.Ordinal)) {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            Debug.Log("consumableOne ");
            //TODO Something after success purchase...
        }
        else if (String.Equals(args.purchasedProduct.definition.id, consumableTwo, StringComparison.Ordinal)) {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            Debug.Log("consumableTwo ");
            //TODO Something after success purchase...
        } else if (String.Equals(args.purchasedProduct.definition.id, consumableThree, StringComparison.Ordinal)) {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            Debug.Log("consumableThree ");
            //TODO Something after success purchase...
        } else {
            Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
        }
        return PurchaseProcessingResult.Complete;
    }
 
 
然后我们看一下完整的代码:
 
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Purchasing;
public class IAPLearn : MonoBehaviour, IStoreListener {
    private static IStoreController m_StoreController;          // The Unity Purchasing system.
    private static IExtensionProvider m_StoreExtensionProvider; // The store-specific Purchasing subsystems.
    public static string consumableOne = "com.usegame.one.50rmb";
    public static string consumableTwo = "com.usegame.two.100rmb";     //这个ID一定要是静态的
    public static string consumableThree = "com.usegame.three.150rmb";
    public static IAPLearn instance;
    void Awake() {
        instance = this;
        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
        builder.AddProduct(consumableOne, ProductType.Consumable, new IDs() {
            {consumableOne,AppleAppStore.Name },//
            //GooglePlay:
            //{consumableOne,GooglePlay.Name },
        });
        builder.AddProduct(consumableTwo, ProductType.Consumable, new IDs() {
            {consumableTwo,AppleAppStore.Name },
        });
        builder.AddProduct(consumableThree, ProductType.Consumable, new IDs() {
            {consumableThree,AppleAppStore.Name },
        });
        UnityPurchasing.Initialize(this, builder);
    }
    void Start() {
        DontDestroyOnLoad(this.gameObject);
    }
    private bool IsInitialized() {
        return m_StoreController != null && m_StoreExtensionProvider != null;
    }
    public void BuyProduct(int id) {
        switch (id) {
            case 1:
                BuyProductID(consumableOne);
                break;
            case 2:
                BuyProductID(consumableTwo);
                break;
            case 3:
                BuyProductID(consumableThree);
                break;
            default :
                Debug.Log("Don't have the number id");
                break;
        }
        
    }
    void BuyProductID(string productId) {   //我们并不能直接用这个函数进行传递参数进去,因为ID都是静态的
        if (IsInitialized()) {
            Product product = m_StoreController.products.WithID(productId);
            if (product != null && product.availableToPurchase) {
                Debug.Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.id));
                m_StoreController.InitiatePurchase(product);
            }
            else {
                Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
            }
        }
        else {
            Debug.Log("BuyProductID FAIL. Not initialized.");
        }
    }
    //AppStore
    public void RestorePurchases() {
        if (!IsInitialized()) {
            Debug.Log("RestorePurchases FAIL. Not initialized.");
            return;
        }
        if (Application.platform == RuntimePlatform.IPhonePlayer ||
            Application.platform == RuntimePlatform.OSXPlayer) {
            Debug.Log("RestorePurchases started ...");
            var apple = m_StoreExtensionProvider.GetExtension<</span>IAppleExtensions>();
            apple.RestoreTransactions((result) => {
                Debug.Log("RestorePurchases continuing: " + result + "If no further messages, no purchases available to restore.");
            });
        }
        else {
            Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current " + Application.platform);
        }
    }
    public void OnInitialized(IStoreController controller, IExtensionProvider extensions) {
        Debug.Log("OnInitialized: Begin");
        m_StoreController = controller;
        m_StoreExtensionProvider = extensions;
        Debug.Log("OnInitialized: Pass");
    }
    public void OnInitializeFailed(InitializationFailureReason error) {
        Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
    }
    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) {
        if (String.Equals(args.purchasedProduct.definition.id, consumableOne, StringComparison.Ordinal)) {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            Debug.Log("consumableOne ");
            //TODO Something after success purchase...
        }
        else if (String.Equals(args.purchasedProduct.definition.id, consumableTwo, StringComparison.Ordinal)) {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            Debug.Log("consumableTwo ");
            //TODO Something after success purchase...
        } else if (String.Equals(args.purchasedProduct.definition.id, consumableThree, StringComparison.Ordinal)) {
            Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
            Debug.Log("consumableThree ");
            //TODO Something after success purchase...
        } else {
            Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
        }
        return PurchaseProcessingResult.Complete;
    }
    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) {
        Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason));
    }
}
 

你可以对比官网上的那个例子,来看一下需要改动的地方都在哪里。
我写了一个测试场景,来看一下结果:
首先是Button上的脚本。
 
using UnityEngine;
using UnityEngine.UI;
public class IAPBuyButton : MonoBehaviour {
    public int productID;
    void Start() {
        GetComponent<</span>Button>().onClick.AddListener(() => IAPLearn.instance.BuyProduct(productID));
    }
}
 

http://a4.qpic.cn/psb?/V13rTjJQ0eYbaU/fnenW3b3l3jVwVTgOrWBezAjuaaHH9TjOT0hZjEPKgw!/b/dGcBAAAAAAAA&ek=1&kp=1&pt=0&bo=.gH7APoB.wADEDU!&su=0178700257&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />

然后我们运行场景,点击按钮。因为在编辑器环境下,总是判定是购买成功的,不会走IAP平台那边的判断,所以结果如下。

http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/y1PMuWc52o40wT65J.3gs4Oi0b2fIGdf2GOxDRbttSQ!/o/dGgBAAAAAAAA&ek=1&kp=1&pt=0&bo=qALlAagC5QEDEDU!&su=1130651921&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />




我们还有另一个方法来实现这个IAP功能。

http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/ru.dP.82QNhuXdKGooC5JiBLJdW6xSSW0Ivgkyj7mS0!/o/dGkBAAAAAAAA&ek=1&kp=1&pt=0&bo=XQMEAV0DBAEDEDU!&su=1206725921&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />

在window下有一个Unity IAP 然后我们点击IAP Catalog。
然后就是如下图这样。
http://r.photo.store.qq.com/psb?/V13rTjJQ0eYbaU/IGWNoE6eIIFllydccmUyJiD6VGuMFpMa289vTnFgfoY!/o/dGkBAAAAAAAA&ek=1&kp=1&pt=0&bo=QANRAkADUQIDEDU!&su=1200610737&tm=1492527600&sce=0-12-12&rf=2-9IAP赚取你的第一桶金" />

我们可以在面板中填写我们的产品信息。这很方便,而且这个unity IAP插件里面有一个IAP button,它把IAP能用到的功能都封装好了,我们可以直接拿来用,减少了开发者的繁琐的工作量。

这个方法,我就不具体写了。
http://www.manew.com/thread-100403-1-1.html
蛮牛里已经有人写过了,还是很详细的。

OK,这个简版的IAP就记录到这里了,因为在国内连接iTunes是很慢的,可能连接很久没有登录,所以,一般情况下,我们可以在连接iTunes的时候给它加一层遮罩,然后限时,规定时间内连接成功,我们就显示,否则,就让玩家重新连接。



0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有