参考资料:http://www.cocoachina.com/bbs/read.php?tid-69165-fpage-2.html
网上很多IAP的教程,但是较少有结合U3D的教程。所以我在此进行简单整理,基本原理就是在传统的IAP流程中加入向U3D传递信息和U3D调用xcode函数这两个特殊点
关于U3D中加入IOS内购,我们需要很清楚的是,肯定是需要使用xcode来进行内购相关编程的。
而一般对于新手和没有接触过xcode编程的同志来说,是有一定困难的。
所以我这里就直接提供大家我做好的内购小插件,只对里面比较重要的代码进行简单讲解。
首先,这个小插件包中又5个xcode编写的代码文件,
这些代码的参考来自:http://blog.csdn.net/slowfei/article/details/7606320
小插件下载地址:http://download.csdn.net/detail/mr_dodododo/6020315
(资源需求2积分哦~自己的劳动成果,希望大家支持谅解哦)
分别是:
InAppPurchase.mm
InAppPurchaseManager.m
InAppPurchaseManager.h
SKProduct+LocalizedPrice.h
SKProduct+LocalizedPrice.m
这些代码的具体讲解我就不提及了,想深究的同志自己学习吧。我只提及重点部分:
1. 如何让U3D可以调用xcode中的函数
调用目的:开始内购流程
方法:
InAppPurchase.mm中
#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>
#import "InAppPurchaseManager.h"
extern "C" {
bool CanPurchase()
{
return [SKPaymentQueue canMakePayments];
}
InAppPurchaseManager *sharedMgr = nil;
void BuySomething( char State[], char Obj[], char Fun[], char Val[] )
{
NSString *nState = [NSString stringWithUTF8String:State];
NSString *nObj = [NSString stringWithUTF8String:Obj];
NSString *nFun = [NSString stringWithUTF8String:Fun];
NSString *nVal = [NSString stringWithUTF8String:Val];
if (sharedMgr == nil) {
sharedMgr = [[InAppPurchaseManager alloc]init];
[sharedMgr loadStore:nState];
}
NSLog(@"Invalid product id: %@" , nState);
[sharedMgr purchaseLevel:nState:nObj:nFun:nVal];
}
void RestoreBuy()
{
if (sharedMgr == nil) {
sharedMgr = [[InAppPurchaseManager alloc]init];
}
[sharedMgr RestoreLevel];
}
}
2. 如何让内购成功与否传递到U3D中
传递目的:让玩家知道自己购买成功与否
方法:
在InAppPurchaseManager.m中
购买成功失败后传递信息给U3D中,让U3D进行响应
// 交易成功
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
UnitySendMessage("AppStore","GoOnSuccess","");
[self recordTransaction:transaction];
[self provideContent:transaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
//
// called when a transaction has been restored and and successfully completed
// 得到恢复和成功地完成交易时调用
- (void)restoreTransaction:(SKPaymentTransaction *)transaction
{
UnitySendMessage("AppStore","GoOnRestore","");
[self recordTransaction:transaction.originalTransaction];
[self provideContent:transaction.originalTransaction.payment.productIdentifier];
[self finishTransaction:transaction wasSuccessful:YES];
}
//
// called when a transaction has failed
// 当交易失败
- (void)failedTransaction:(SKPaymentTransaction *)transaction
{
UnitySendMessage("AppStore","GoOnFail","");
if (transaction.error.code != SKErrorPaymentCancelled)
{
// error!
[self finishTransaction:transaction wasSuccessful:NO];
}
else
{
// this is fine, the user just cancelled, so don’t notify
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
}
- (void)provideContent:(NSString *)productId
{
if ([productId isEqualToString:AppState])
{
// enable the pro features
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:AppState ];
[[NSUserDefaults standardUserDefaults] synchronize];
UnitySendMessage([ObjName UTF8String],[FunName UTF8String],[ValName UTF8String]);
}
}
UnitySendMessage([ObjName UTF8String],[FunName UTF8String],[ValName UTF8String]);
主要就是这句代码,还记得之前我们的
void BuySomething( char State[], char Obj[], char Fun[], char Val[] )
这个函数传入的值吗?后面的这3个参数就是在这里发挥作用的。将在U3D中做出对应的响应。
那么这里我对xcode中的简单介绍就到此为止,因为具体的内购流程,网上有许多教程,我之前发的参考教程中就有所提及。我这里就不赘述了。
那么下面我们看U3D中具体应该如何来使用这些xcode中编写的方法
首先导入自制的小插件,导入后将拥有以下这些文件:
其中5个xcode文件我之前已经简单讲解了。他们的作用就是完成内购流程。
那么我们来讲讲BuyBtn.cs和AppStore.cs两个文件
BuyBtn.cs
using UnityEngine;
using System.Collections;
public class BuyBtn : MonoBehaviour {
public string IapID;
public string ObjName;
public string FunName;
public string ValName;
public GameObject WaitingOb;
public GameObject mTipWindow;
void OnClick(){
Instantiate(WaitingOb);
mTipWindow.transform.position = new Vector3(3000, 0, 0);
AppStore.BuySomething(IapID, ObjName, FunName, ValName);
}
}
这里前提是游戏使用了NGUI进行UI方面的开发。将这个脚本拖入按钮之上,点击按钮后,我们将创建一个等待购买的等待特效(或者面板)主要目的是防止玩家进行其它操作。然后将购买的面板移向摄像机外(可以根据自身需求进行更改)。然后调用AppStore中的全局函数BuySomething
其中IapID是我们在创建内购时注册的唯一内购ID
ObjName是我们内购成功后希望调用的U3D函数所在对象的对象名
FunName是希望调用的函数名
ValName是参数名(若没有参数可以不填写)
AppStore.cs
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class AppStore : MonoBehaviour {
[DllImport ("__Internal")]
public static extern bool CanPurchase();//CanBuy?
[DllImport ("__Internal")]
public static extern void BuySomething( string PID, string ObjName, string FunName, string ValName );
[DllImport ("__Internal")]
public static extern void RestoreBuy();
public GameObject buyfail;
public GameObject buysuccess;
public GameObject NetFail;
public GameObject ReOver;
void GoOn(){
GameObject tmp = null;
tmp = GameObject.Find("paymoneywaittingmask(Clone)");
if( tmp != null )
Destroy(tmp);
}
//BuySuccess
void GoOnSuccess(){
GameObject tmp = null;
tmp = GameObject.Find("paymoneywaittingmask(Clone)");
if( tmp != null )
Destroy(tmp);
Instantiate(buysuccess,buysuccess.transform.position,buysuccess.transform.rotation);
}
//BuyFail
void GoOnFail(){
GameObject tmp = null;
tmp = GameObject.Find("paymoneywaittingmask(Clone)");
if( tmp != null )
Destroy(tmp);
Instantiate(buyfail,buyfail.transform.position,buyfail.transform.rotation);
}
void GoOnRestore(){
GameObject tmp = null;
tmp = GameObject.Find("paymoneywaittingmask(Clone)");
if( tmp != null )
Destroy(tmp);
Instantiate(ReOver,ReOver.transform.position,ReOver.transform.rotation);
}
void CheckNet()
{
GameObject tmp = null;
tmp = GameObject.Find("paymoneywaittingmask(Clone)");
if( tmp != null )
Destroy(tmp);
Instantiate(NetFail, NetFail.transform.position, NetFail.transform.rotation);
}
}
函数我基本就不解释了,一看就明白了。其中Buyfail BuySuccess NetFail ReOver几个对象,是我们需要在购买成功,购买失败等情况下在游戏界面中显示的特效。比如购买成功后屏幕上显示购买成功的特效。根据自身需求进行创建或者改变即可。
而具体想要调用的购买函数就得你自己来写了,具体购买得到什么解锁什么。你需要自己完成一个专门的购买脚本,然后使用BuySomething传递对应的三个参数来调用你自己创建的购买函数。比如你在场景中创建一个GameObject命名为Buy,然后创建了一个任意脚本,在这个脚本上有一个添加游戏中金币的函数AddGem(string gems)。然后把这个脚本拖给了Buy。那么我们就使用BuySomething("com.300gem","Buy","AddGem","100")。那么在内购成功后,xcode向U3D传递消息,便会调用你场景中名为Buy的对象中的AddGem函数,参数为100。这样基本就大功告成了。
需要注意的是:在U3D导出xcode工程文件后,一定要记住添加StoreKit.framework,否则工程会报错的哦~~
在哪里添加framework文件?如图,点击图中右下方的小加号~
结束,介绍的很浅显很粗略,有错误希望大家指正,如果有任何问题可以邮件联系我哦~~邮箱地址:tpandme@163.com