本人是一个Unity忠实爱好者,鉴于网上关于Unity的内置付费教程 少之甚少,本人就把自己倒腾过的IAp分享出来,仅供大家参考。
一、搭建号沙盒环境( 详细请看:http://xiaominghimi.blog.51cto.com/2614927/706415)

二、IAP付费流程图:

总体流程图如下:
<ignore_js_op>

详细流程图分为带服务端验证和不带服务端验证,本文研究的是带服务端验证,流程图如下:

<ignore_js_op>

在Unity中制作IAP主要思想和OC是一样的,只需更改输入接口和输出接口,所以本文主要围绕如何通过C#以插件的形式,在OC跟C#之间建立连接,本质是非托管跟托管之间的连接(托管是可以再公共语言运行库(CLR)上运行的)。

三、接来下我以代码的形式,简短的将整个过程贯穿起来。

首先点击付费按钮之后,调用StoreKit.Install(产品的部分ID);//完整这样com.XXX.XXXX.iap.50,此处填com.XXX.XXXX.iap。StoreKit.Install(产品的部分ID)会调用插件里_StoreKitInstall(productIdPrefix),_StoreKitInstall(productIdPrefix)跟OC建立起了连接,调用相应的OC函数,最后会在OC一个变量中保存产品的部分ID信息。

其次当用户点了某一个购买按钮,向OC发送一次请求,当OC受到请求后,会向App store发送请求,验证当前产品ID是否合法,合法的话,会返回BaseKey,productID,OrderId信息。 UnitySendMessage(“Config”, “BuyComplate_CallBack”, [json UTF8String]);通过这个函数,完成OC和C#一次回调。以json的形式返回给C#产品的订单信息。(UnitySendMessage函数中Config是放置购买脚本的GameObject,BuyComplate_CallBack是购买脚本里面的回调函数)

最后,当客户端收到产品订单后,传给本地服务器,本地服务器拿到产品订单后,再跟App store进行一次验证,返回给客户端验证结果,客户端在更新虚拟货币信息。

四、核心代码
StoreKitPluginEntry.mm和StoreKit.cs是连接OC和C#的桥梁,具体代码如下:

  1. StoreKitPluginEntry.mm
  2. static IAPTransactionObserver *observer;
  3. static NSString* CreateNSString (const char* string) {
  4. return [NSString stringWithUTF8String:(string ? string : "")];
  5. }
  6. extern "C" void _StoreKitInstall(const char *productIdPrefix) {
  7. if (observer == nil) {
  8. observer = [[IAPTransactionObserver alloc] initWithProductIdPrefix:CreateNSString(productIdPrefix)];
  9. }
  10. }
  11. extern "C" void _StoreKitBuy(const char *productName) {
  12. [observer queuePayment:CreateNSString(productName)];
  13. }

复制代码

  1. StoreKit.cs
  2. static string productIdPrefix_;
  3. public static void Install(string productIdPrefix) {
  4. productIdPrefix_ = productIdPrefix;
  5. #if UNITY_IPHONE && !UNITY_EDITOR
  6. _StoreKitInstall(productIdPrefix);
  7. #endif
  8. }
  9. public static void Buy(string productName) {
  10. #if UNITY_IPHONE && !UNITY_EDITOR
  11. _StoreKitBuy(productName);
  12. #endif
  13. }
  14. #if UNITY_IPHONE
  15. [DllImport("__Internal")]
  16. private static extern void _StoreKitInstall(string productIdPrefix);
  17. [DllImport ("__Internal")]
  18. private static extern void _StoreKitBuy(string productName);
  19. #endif

复制代码

  1. [DllImport ("__Internal")]

复制代码

是托管跟非托管的桥梁。以下是Mono官网对 [DllImport ("__Internal")] 的说明

To make the runtime lookup the symbol in the current executable, use the special library name __Internal like this, in your DllImport attribute:

  1. using System.Runtime.InteropServices; [DllImport ("__Internal", EntryPoint="DoSomething")]static extern void DoSomething

复制代码

The “__Internal” library name will instruct Mono not to look this up in an external library, but to try to satisfy the symbol referenced (DoSomething) in the current executable image.
Buy.cs购买代码

  1. public void BuyComplate_CallBack(string result){
  2. string url="";
  3. print("result:"+ result);
  4. url+="m=XXX&a=XXX&uid="+player.PlayerID;
  5. Hashtable json=(Hashtable)MiniJSON.JsonDecode(result);//json解析器
  6. productInfo=json["productID"].ToString().Substring(productInfo.Length+1);//截取购买的类型
  7. WWWForm resultPost=new WWWForm();//由于json字节过长,不能采用get方式提交,所以选用Post方式提交
  8. resultPost.AddField("basyKey",json["BaseKey"].ToString());
  9. resultPost.AddField("OrderId",json["OrderId"].ToString());
  10. resultPost.AddField("productID",json["productID"].ToString());
  11. StartCoroutine(BuyComplate(url,str,resultPost));
  12. }
  13. /*验证是否购买成功,如果成功,更新虚拟货币数量*/
  14. IEnumerator BuyComplate(string url,string productId,WWWForm buyInfo)//
  15. {
  16. WWW productInfo=new WWW(url,buyInfo);
  17. yield return productInfo;
  18. //print("data:"+productInfo.text);
  19. if(productInfo.error==null)
  20. {
  21. Hashtable result=(Hashtable)MiniJSON.JsonDecode(productInfo.text);
  22. if(result["status"].ToString()=="ok")
  23. {
  24. switch(productId)
  25. {
  26. case "tier1":player.Gemstone+=50;break;
  27. }
  28. }
  29. }
  30. }

复制代码

到此,Unity之IAP讲述完毕,以下附上原工程和对应的Json解析器。ECPurchase和testIap下载
水平有限,不足之处望大家指正。

原文链接 http://blog.chukong-inc.com/index.php/2012/01/05/unity3d-%e4%b9%8biap/

Unity3D 之IAP的更多相关文章

  1. Unity3D如何有效地组织代码?(转)

    问题: Unity3D可以说是高度的Component-Based Architecture,同时它的库提供了大量的全局变量.如何来组织代码呢? 答: - Unity有一些自身的约定,譬如项目里的Ed ...

  2. unity3d 嵌入iOS的 In App Purchase 应用程序内购买

    Unity做东西是快,但是有些功能是需要额外开发的,比如 IAP (In App Purchase,应用程序内购买) 还好unity提供了灵活的扩展功能,允许嵌入原生代码来做一些unity未实现的功能 ...

  3. Unity3D如何有效地组织代码?

    本文整理自知乎,原文链接:http://www.zhihu.com/question/21070379 问题: Unity3D可以说是高度的Component-Based Architecture,同 ...

  4. Unity3D与iOS的交互

    1. 关于Unity3D Unity3D(以下简称U3D)是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开 ...

  5. Unity3d学习 预设体(prefab)的一些理解

    之前一直在想如果要在Unity3d上创建很多个具有相同结构的对象,是如何做的,后来查了相关资料发现预设体可以解决这个问题! 预设体的概念: 组件的集合体 , 预制物体可以实例化成游戏对象. 创建预设体 ...

  6. Unity3d入门 - 关于unity工具的熟悉

    上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...

  7. TDD在Unity3D游戏项目开发中的实践

    0x00 前言 关于TDD测试驱动开发的文章已经有很多了,但是在游戏开发尤其是使用Unity3D开发游戏时,却听不到特别多关于TDD的声音.那么本文就来简单聊一聊TDD如何在U3D项目中使用以及如何使 ...

  8. warensoft unity3d 更新说明

    warensoft unity3d 组件的Alpha版本已经发布了将近一年,很多网友发送了改进的Email,感谢大家的支持. Warensoft Unity3D组件将继续更新,将改进的功能如下: 1. ...

  9. Unity3D框架插件uFrame实践记录(一)

    1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...

随机推荐

  1. HDU 5732 Subway(2016多校1J,树的重心 + 哈希)

    题目链接  2016多校1 Problem J 题意  给定两棵相同的树,但是编号方案不同.求第一棵树上的每个点对应的第二棵树上的点.输出一种方案即可. 首先确定树的直径的中点.两棵树相等意味着两棵树 ...

  2. springmvc适配器的应用

         前言     关于SpringMVC初始化ContextLoader中的XMLWebApplicationContext,以及DispatcherServlet初始化等等,这样的原理 已经有 ...

  3. 1424 零树 (树形DP)

    1424 零树 题意 给出一棵树,每次可以选择一个包含节点 1 的连通块,将所有的节点的权值同时加 1 或减 1 ,问最少多少次操作使所有节点权值变为 0 . 分析 这种题意简单的题目好处就是能很快知 ...

  4. 线段树【p2801】教主的魔法

    Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.--.N. 每个人的 ...

  5. 分层图【p4568】 [JLOI2011]飞行路线

    Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在nn个城市设有业务,设这些城市分别标记为\(0\)到\(n−1\),一共有\(m\)种航线 ...

  6. android如何取消闹铃

    取消闹钟: Intent intent = new Intent(context, TestReceiver.class); PendingIntent pi = PendingIntent.getB ...

  7. TCP/IP,http,socket,长连接,短连接 —— 小结

    TCP/IP是什么? TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层.    在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议.    在传输层中有TCP协议 ...

  8. 我也来说说js的事件机制

    原文链接:http://www.w3cfuns.com/notes/17398/8062de2558ef495ce6cb7679f940ae5c.html 学js,不懂事件机制,基本可以说学了js,就 ...

  9. java学习之输入,输出流

    输入流与输出流 1,流的分类:字节流和字符流 区别如下: 1,字节流(8位Unicode)在操作的时候本身是不会用到缓冲区(内存)的byte,是与文件本身直接操作的,而字符流(16位Unicode)在 ...

  10. jQuery的DOM操作之加入元素和删除元素

    加入元素: .append()--在目标元素之后加入元素. .prepend()--在目标元素之前加入元素. .after()--在目标元素之后换行加入元素: .before()--在目标元素之前加入 ...