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

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


一、Unity3d  To  iOS:


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

public class SdkToIOS: MonoBehaviour
{
	//平台接入开关
	public static bool isOpenPlatform = false;
	
	//导入定义到.m文件中的C函数
    [DllImport("__Internal")]
    private static extern void _PlatformInit();
    
    //定义接口函数供游戏逻辑调用
   	 public static void InitSDK()
  	{
        if (isOpenPlatform)
        {
            _PlatformInit();
        }
	}	
}

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

//  MyIOSSdk.h


#import <Foundation/Foundation.h>

@interface MyIOSSdk : NSObject

@end

//  MyIOSSdk.m

#import "MyIOSSdk.h"

//这里引用SDK的头文件
#import "SDKPlatform.h"

#if defined(__cplusplus)
extern "C"{
#endif
    extern void UnitySendMessage(const char *, const char *, const char *);
    extern NSString* _CreateNSString (const char* string);
#if defined(__cplusplus)
}
#endif

//*****************************************************************************

@implementation MyIOSSdk

//**********************
//message tools

+ (void)sendU3dMessage:(NSString *)messageName param:(NSDictionary *)dict
{
    NSString *param = @"";
    if ( nil != dict ) {
        for (NSString *key in dict)
        {
            if ([param length] == 0)
            {
                param = [param stringByAppendingFormat:@"%@=%@", key, [dict valueForKey:key]];
            }
            else
            {
                param = [param stringByAppendingFormat:@"&%@=%@", key, [dict valueForKey:key]];
            }
        }
    }
    UnitySendMessage("SDK_Object", [messageName UTF8String], [param UTF8String]);
}

//**********************
//SDK fun

//初始化SDK
-(void)SDKInit
{
	SDKcfg *cfg = [[[SDKcfg alloc] init] autorelease];
	cfg.appid =123456;
	cfg.appKey =@"aoaoaoaoaoaoaoaoaoaoaoaoaaoaoaoaoaoaoao";
	cfg.orientation = UIDeviceOrientationLandscapeLeft;
	//调用SDK的初始化函数
	[[SDKPlatform defaultPlatform] SDKInit:cfg];
	//添加回调监听
	[[SDKPlatform defaultPlatform] addObserver:self selector:@selector(SNSInitResult:) name:(NSString *)kInitNotification object:nil];
}

//获取用户ID
-(NSString*)SDKGetUserID
{
	[[SDKPlatform defaultPlatform] SDKGetUserID];
}

//**********************
//call back fun

//初始化更新回调
- (void)SNSInitResult:(NSNotification *)notify
{
    [MyIOSSdk sendU3dMessage:@"SDKMsgInit" param:nil];
}

@end


//*****************************************************************************

#if defined(__cplusplus)
extern "C"{
#endif
    
	//字符串转化的工具函数
	
    NSString* _CreateNSString (const char* string)
    {
        if (string)
            return [NSString stringWithUTF8String: string];
        else
            return [NSString stringWithUTF8String: ""];
    }
    
    char* _MakeStringCopy( const char* string)
    {
        if (NULL == string) {
            return NULL;
        }
        char* res = (char*)malloc(strlen(string)+1);
        strcpy(res, string);
        return res;
    }
    
    static MyIOSSdk *mySDK;


	//供u3d调用的c函数
  
    void _PlatformInit()
    {
        if(mySDK==NULL)
        {
            mySDK = [[MyIOSSdk alloc]init];
        }
        [lsSDK SDKInit];
    }
	
	//注意这个函数是返回字符串
	const char* _PlatformGetUin()
	{
		if(lsSDK==NULL)
        {
            lsSDK = [[MyIOSSdk alloc]init];
        }
		return _MakeStringCopy([[lsSDK SDKGetUserID] UTF8String]);
	}
    
#if defined(__cplusplus)
}
#endif

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

[DllImport ("__Internal")]
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函数,我还在消息接受脚本中写过一个消息参数的解析:

	void ParseMsg(string msg, out Dictionary<string, string> dicMsg){
		if( null == msg || 0 == msg.Length ){
			dicMsg = null;
			return;
		}
		dicMsg = new Dictionary<string, string>();
		string[] msgArray = msg.Split(‘&‘);
		for( int i=0; i<msgArray.Length; i++){
			string[] elementArray = msgArray[i].Split(‘=‘);
			dicMsg.Add(elementArray[0],elementArray[1]);
		}
	}

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


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


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


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


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


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

上一篇:稀疏编码最优化解法--概述


下一篇:团队应该如何写软件?