Unity3D 之IAP

Published on 2012 年 1 月 5 日, by wuyuan in iOS技术.

本人是一个Unity忠实爱好者,鉴于网上关于Unity的内置付费教程 少之甚少,本人就把自己倒腾过的IAp分享出来,仅供大家参考。

一、搭建号沙盒环境( 详细请看:http://xiaominghimi.blog.51cto.com/2614927/706415)

二、IAP付费流程图:

总体流程图如下:

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

在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#的桥梁,具体代码如下:

Source code    
StoreKitPluginEntry.mm
 
static IAPTransactionObserver *observer;
static NSString* CreateNSString (const char* string) {
    return [NSString stringWithUTF8String:(string ? string : "")];
}
extern "C" void _StoreKitInstall(const char *productIdPrefix) {
    if (observer == nil) {
        observer = [[IAPTransactionObserver alloc] initWithProductIdPrefix:CreateNSString(productIdPrefix)];
 
    }
}
extern "C" void _StoreKitBuy(const char *productName) {
    [observer queuePayment:CreateNSString(productName)];
}
Source code    
StoreKit.cs
 
	static string productIdPrefix_;
 
	public static void Install(string productIdPrefix) {
		productIdPrefix_ = productIdPrefix;
		#if UNITY_IPHONE && !UNITY_EDITOR
			_StoreKitInstall(productIdPrefix);
		#endif
	}
 
	public static void Buy(string productName) {
		#if UNITY_IPHONE && !UNITY_EDITOR
			_StoreKitBuy(productName);
		#endif
	}
 
	#if UNITY_IPHONE
	[DllImport("__Internal")]
	private static extern void _StoreKitInstall(string productIdPrefix);
	[DllImport ("__Internal")]
	private static extern void _StoreKitBuy(string productName);
	#endif

[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:

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购买代码

Source code    
public void BuyComplate_CallBack(string result){
		string url="";
		print("result:"+ result);
		 url+="m=XXX&a=XXX&uid="+player.PlayerID;
		Hashtable json=(Hashtable)MiniJSON.JsonDecode(result);//json解析器
		productInfo=json["productID"].ToString().Substring(productInfo.Length+1);//截取购买的类型
		 WWWForm resultPost=new WWWForm();//由于json字节过长,不能采用get方式提交,所以选用Post方式提交
		  resultPost.AddField("basyKey",json["BaseKey"].ToString());
		  resultPost.AddField("OrderId",json["OrderId"].ToString());
		 resultPost.AddField("productID",json["productID"].ToString());
		StartCoroutine(BuyComplate(url,str,resultPost));
	}
 
	/*验证是否购买成功,如果成功,更新虚拟货币数量*/
	IEnumerator BuyComplate(string url,string productId,WWWForm buyInfo)//
	{
		WWW productInfo=new WWW(url,buyInfo);
		yield return productInfo;
		//print("data:"+productInfo.text);
		if(productInfo.error==null)
		{
			Hashtable result=(Hashtable)MiniJSON.JsonDecode(productInfo.text);
			if(result["status"].ToString()=="ok")
			{
				 switch(productId)
				{
				    case "tier1":player.Gemstone+=50;break;
				}
			}
		}
	}

到此,Unity之IAP讲述完毕,以下附上原工程和对应的Json解析器。ECPurchase和testIap下载

水平有限,不足之处望大家指正。

时间: 2024-08-08 18:57:20

Unity3D 之IAP的相关文章

2Unity3D教程宝典之插件篇:Unity3D插件详细评测及教学下载

转载自风宇冲Unity3D教程学院 http://blog.sina.com.cn/s/blog_471132920101crh3.html 引言:想用Unity3D制作优秀的游戏,插件是必不可少的.工欲善其事必先利其器.本文主旨是告诉使用Unity3D引擎的同学们如何根据需求选择适当的工具.为此我写了插件的经验及理论讲解,涉及插件的 学习/辨别/选择/配合.也写了插件的 评测/教程/下载.关于评测,带有一定的主观性,仅供参考.关于教程,热门插件网上已经有很多教程了,本文提供链接,网上资料少的插

Unity3D如何有效地组织代码?

欢迎来到unity学习.unity培训.unity企业培训教育专区,这里有很多U3D资源.U3D培训视频.U3D教程.U3D常见问题.U3D项目源码,我们致力于打造业内unity3d培训.学习第一品牌. Unity3D可以说是高度的Component-Based Architecture,同时它的库提供了大量的全局变量. 准确地说,代码作为Unity项目里的一种资源,此问题应该扩展到如何组织Unity资源.简单说说我们的经验:1.  Unity有一些自身的约定,譬如项目里的Editor,Plug

泰课在线的:HTC Vive 基础入门 基于Unity3D引擎

任务1: 关注公众号即可下载本视频教程 任务2: 01-概述 07:08 任务3: 02-HTC Vive设备的安装 08:33 任务4: 03-下载Steam与SteamVR 03:05 任务5: 04-使用Steam VR 调试设备 14:40 任务6: 05-下载Unity3D 03:24 任务7: 06-配置Unity VR开发环境 09:43 任务8: 07-Steam VR插件的基本使用 20:25 任务9: 08-VR开发初体验 07:15 .net大神老师给我扫盲了,从一点没接触

unity3d 项目源码下载链接

2-1 炉石传说 客户端加服务器端 链接:http://pan.baidu.com/s/1dDKY3Fr 密码:c03q 2-2 新仙剑奇侠传 链接:http://pan.baidu.com/s/1b4QVqI 密码:dic5 2-3 unity3d 战斗卡牌<变身吧主公>客户端+服务器源码 链接:http://pan.baidu.com/s/1kUpot51 密码:i02u 2-4 降临OL-U3D全套源码 链接:http://pan.baidu.com/s/1sktLQ5v 密码:we0g

Unity3D 视频教程列表,列表共 91 套

[000001]<Unity3D Platform 中文视频教程>[7课时] [000002]<Unity3D 游戏蛮荒之地教学视频>[15课时] [000003]<Unity3D 坦克克星视频教程>[9课时] [000004]<Unity3D 太空射击游戏中文视频>[17课时] [000005]<Unity3D 切水果视频教程>[9课时] [000006]<Unity3D 精神時光屋>[5课时] [000007]<Unity3

unity3d中的物体,在Scene窗口中可以看到,而在Game窗口中看不到的原因

unity3d中的物体,在Scene窗口中可以看到,而在Game窗口中看不到的原因: 多半是因为物体所属Layer与照相机的culling mask不一致导致的,或者超出照相机的可视范围. 如果游戏中有多个相机,每个相机都有自己的可视范围和culling mask,物体在移动的过程中,进入不同的相机,其可见性可能是变化的,取决与物体所属Layer与当前相机是否一致

IAP

release_check_url := "https://buy.itunes.apple.com/verifyReceipt" debug_check_url := "https://sandbox.itunes.apple.com/verifyReceipt" 请求数据: {"receipt-data":"xxxxxxxx"} 苹果的返回值如下: { "receipt": { "origin

unity3d编程日志

2014/4/27 编写脚本的时候,加入了中文凝视,发现console面板有非常多不可思议的bug.查了一下发现是由于monodevelop脚本中文凝视报错,而英文凝视不会受影响. 解决方法:把凝视放在//...//中,bug就消失了. 2014/8/22 unity3d常常会报这种错误:object reference can't add to an instance object.这种情况出现是由于在调用的时候没有找到那个对象,解决方法,加if推断方法推断是否存在.排除异常

Unity3D在Android平台使用嵌入式数据库Sqlite,解决无法找到数据库文件的问题

做一个需要嵌入式数据库Sqlite 的unity3d项目,在pc机上运行良好,需要发布到Android平台上,于是,各种坑爹...会遇到找不到数据库文件的问题.当在pc机上使用sqlite时,当执行SqliteConnection dbConnection = new SqliteConnection("data source = test.db");语句时,如果有这个数据库文件则建立连接,如果没有则创建出这个文件,然后建立连接.当在Android平台上时,扯淡的事情就开始了,总之便不