首页 > 代码库 > Unity3d与iOS交互开发——接入平台SDK必备技能

Unity3d与iOS交互开发——接入平台SDK必备技能

来源:http://blog.csdn.net/zhao_yin/article/details/18401989

前言废话:开发手机游戏都知道,你要接入各种平台的SDK。那就需要Unity3d与iOS中Objective-C的函数有交互,所以你就需要用到如下内容:

 

一、Unity3d  To  iOS:

 

1、创建一个C#文件 SdkToIOS.cs 这是调用iOS函数的接口:

 

[csharp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. public class SdkToIOS: MonoBehaviour  
  2. {  
  3.     //平台接入开关  
  4.     public static bool isOpenPlatform = false;  
  5.       
  6.     //导入定义到.m文件中的C函数  
  7.     [DllImport("__Internal")]  
  8.     private static extern void _PlatformInit();  
  9.       
  10.     //定义接口函数供游戏逻辑调用  
  11.      public static void InitSDK()  
  12.     {  
  13.         if (isOpenPlatform)  
  14.         {  
  15.             _PlatformInit();  
  16.         }  
  17.     }     
  18. }  

 

2、编写与接口对应的Objective-c函数:

 

 

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. //  MyIOSSdk.h  
  2.   
  3.   
  4. #import <Foundation/Foundation.h>  
  5.   
  6. @interface MyIOSSdk : NSObject  
  7.   
  8. @end  

 

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. //  MyIOSSdk.m  
  2.   
  3. #import "MyIOSSdk.h"  
  4.   
  5. //这里引用SDK的头文件  
  6. #import "SDKPlatform.h"  
  7.   
  8. #if defined(__cplusplus)  
  9. extern "C"{  
  10. #endif  
  11.     extern void UnitySendMessage(const charchar *, const charchar *, const charchar *);  
  12.     extern NSString* _CreateNSString (const char* string);  
  13. #if defined(__cplusplus)  
  14. }  
  15. #endif  
  16.   
  17. //*****************************************************************************  
  18.   
  19. @implementation MyIOSSdk  
  20.   
  21. //**********************  
  22. //message tools  
  23.   
  24. + (void)sendU3dMessage:(NSString *)messageName param:(NSDictionary *)dict  
  25. {  
  26.     NSString *param = @"";  
  27.     if ( nil != dict ) {  
  28.         for (NSString *key in dict)  
  29.         {  
  30.             if ([param length] == 0)  
  31.             {  
  32.                 param = [param stringByAppendingFormat:@"%@=%@", key, [dict valueForKey:key]];  
  33.             }  
  34.             else  
  35.             {  
  36.                 param = [param stringByAppendingFormat:@"&%@=%@", key, [dict valueForKey:key]];  
  37.             }  
  38.         }  
  39.     }  
  40.     UnitySendMessage("SDK_Object", [messageName UTF8String], [param UTF8String]);  
  41. }  
  42.   
  43. //**********************  
  44. //SDK fun  
  45.   
  46. //初始化SDK  
  47. -(void)SDKInit  
  48. {  
  49.     SDKcfg *cfg = [[[SDKcfg alloc] init] autorelease];  
  50.     cfg.appid =123456;  
  51.     cfg.appKey =@"aoaoaoaoaoaoaoaoaoaoaoaoaaoaoaoaoaoaoao";  
  52.     cfg.orientation = UIDeviceOrientationLandscapeLeft;  
  53.     //调用SDK的初始化函数  
  54.     [[SDKPlatform defaultPlatform] SDKInit:cfg];  
  55.     //添加回调监听  
  56.     [[SDKPlatform defaultPlatform] addObserver:self selector:@selector(SNSInitResult:) name:(NSString *)kInitNotification object:nil];  
  57. }  
  58.   
  59. //获取用户ID  
  60. -(NSString*)SDKGetUserID  
  61. {  
  62.     [[SDKPlatform defaultPlatform] SDKGetUserID];  
  63. }  
  64.   
  65. //**********************  
  66. //call back fun  
  67.   
  68. //初始化更新回调  
  69. - (void)SNSInitResult:(NSNotification *)notify  
  70. {  
  71.     [MyIOSSdk sendU3dMessage:@"SDKMsgInit" param:nil];  
  72. }  
  73.   
  74. @end  
  75.   
  76.   
  77. //*****************************************************************************  
  78.   
  79. #if defined(__cplusplus)  
  80. extern "C"{  
  81. #endif  
  82.       
  83.     //字符串转化的工具函数  
  84.       
  85.     NSString* _CreateNSString (const char* string)  
  86.     {  
  87.         if (string)  
  88.             return [NSString stringWithUTF8String: string];  
  89.         else  
  90.             return [NSString stringWithUTF8String: ""];  
  91.     }  
  92.       
  93.     char* _MakeStringCopy( const char* string)  
  94.     {  
  95.         if (NULL == string) {  
  96.             return NULL;  
  97.         }  
  98.         char* res = (char*)malloc(strlen(string)+1);  
  99.         strcpy(res, string);  
  100.         return res;  
  101.     }  
  102.       
  103.     static MyIOSSdk *mySDK;  
  104.   
  105.   
  106.     //供u3d调用的c函数  
  107.     
  108.     void _PlatformInit()  
  109.     {  
  110.         if(mySDK==NULL)  
  111.         {  
  112.             mySDK = [[MyIOSSdk alloc]init];  
  113.         }  
  114.         [lsSDK SDKInit];  
  115.     }  
  116.       
  117.     //注意这个函数是返回字符串  
  118.     const char* _PlatformGetUin()  
  119.     {  
  120.         if(lsSDK==NULL)  
  121.         {  
  122.             lsSDK = [[MyIOSSdk alloc]init];  
  123.         }  
  124.         return _MakeStringCopy([[lsSDK SDKGetUserID] UTF8String]);  
  125.     }  
  126.       
  127. #if defined(__cplusplus)  
  128. }  
  129. #endif  


值得一提的是在上面的代码中特意写了一个返回字符串的例子,因为你要获取用户ID 、昵称什么的。对应在cs文件中导入函数如下:

 

 

[csharp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. [DllImport ("__Internal")]  
  2. private static extern string _PlatformGetUin();  

这里的const char* 会被C#自动转换成string因为在m文件中使用了内存申请,该段内存自然是处在堆内存中,这样转成string符合c#的内存管理机制,我们不用担心它的释放问题。

 

 

3、在你的工程目录中找个地方保存iOS的文件

打包出XCode工程后导入进去,加入你的SDK就可以了。

有一点需要说明,如果存放目录为\Assets\Plugins\iOS,那么Unity3d会自动将该目录下的所有文件(暂不支持子文件夹)当做插件文件打包到Xcode工程下的Libraries目录下,这样你就不需要在手动添加了,否则会报错重复声明什么的。

这种文件各个平台会有多个,可以使用同一头文件且定义的C函数名也都相同,这样更有利于多版本管理。

 

二、iOS To  Unity3d

这个在上面的 MyIOSSdk.m 文件中已经有剧透了,就是利用unity3d 的UnitySendMessage函数,其中参数1是场景中接受消息的对象,参数2是要执行的函数名,参数3为传入参数,只要按照如下步骤就可以实现这个机制:

1、在场景中创建一个对象用于接受iOS消息,或者用现有的也可以;

2、为SDK消息写一个脚本,里面包含各种消息函数;

3、将脚本挂到之前创建的对象上完事;

需要注意:这个对象在场景切换时候要始终存在,或者你在每个场景中都加个这玩意也可以,总之只要能收到消息就行了;

另外,针对参数的传递对应上面的sendU3dMessage函数,我还在消息接受脚本中写过一个消息参数的解析:

 

[csharp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void ParseMsg(string msg, out Dictionary<string, string> dicMsg){  
  2.     if( null == msg || 0 == msg.Length ){  
  3.         dicMsg = null;  
  4.         return;  
  5.     }  
  6.     dicMsg = new Dictionary<string, string>();  
  7.     string[] msgArray = msg.Split(‘&‘);  
  8.     for( int i=0; i<msgArray.Length; i++){  
  9.         string[] elementArray = msgArray[i].Split(‘=‘);  
  10.         dicMsg.Add(elementArray[0],elementArray[1]);  
  11.     }  
  12. }  


这个我自己都还没有实际使用过,有错误自行解决大致是这样。

 

 

ps:关于SDK的接入还有 android版本的尚未研究网上有很多可以参照;

 

pps:SDK多版本管理和研究我也在摸索中,哪位大神比较熟悉不吝赐教,本人万分感激,之前到是看过这个http://www.xuanyusong.com/archives/2418#comments

 

ppps: 这种交互方式在iOS的模拟器上貌似不行,测试请使用真机;

 

pppps:转载请注明来自:http://blog.csdn.net/zhao_yin