Unity3D 开发游戏需要接入平台方的SDK才能够正式发布,本文记录IOS SDK接入的流程。


Unity与IOS的互调


要实现游戏SDK的接入,首先要解决的是Unity3D与原生IOS代码之间的相互调用问题。Unity使用C#作为开发语言,而IOS采用Objective-C作为开发语言,如何让C#调用OC代码,或者让OC调用C#代码。所幸OC和C#都支持直接嵌入C/C++代码,这里使用C作为两者之间的桥梁。


为了简化两者之间的接口调用和数据传递,在设计Unity与IOS SDK之间的接口时,Unity调用SDK只有一个接口,而SDK调用Unity也只有一个接口。由于平台方的SDK差异性较大,如何保证一个接口可以解决问题?这里我们开发了一个通用SDK层,游戏只会与通用SDK层交互,而由通用SDK层再与具体的平台SDK对接。


Unity中调用SDK层的功能:

usingSystem.Runtime.InteropServices;usingCross;usingUnityEngine;namespaceMuGame{publicclassIOSPlatformSDK:IPlotformSDK{//!--IOS插件声明,所有unity调用iosSDK插件走这里[DllImport("__Internal")]publicstaticexternvoidCallSDKFunc(stringtype,stringjsonpara);

unity中所有的调用都转化为CallSDKFunc,该函数由通用SDK提供,参数type表示功能分类,jsonpara是以json字串表示的一系列参数。


通用SDK调用返回结果给Unity

//!---------------------------外部接口声明--------------------------------------------#ifdefined(__cplusplus)extern"C"{#endifexternvoidUnitySendMessage(constchar*,constchar*,constchar*);#ifdefined(__cplusplus)}#endif

这里使用unityengine.dll提供的C接口UnitySendMessage,这里第1个char* 表示接受该消息的GameObject的name, 第2个表示该GameObject的脚本中接受消息的函数名,第3个表示传递的数据,这里我们还是使用json来传递,同时附带消息类型。


SDK暴露的C接口的声明与定义

#ifdefined(__cplusplus)extern"C"{#endif//游戏层访问SDK的接口voidCallSDKFunc(char*type,char*jsonpara){if(connector==NULL){connector=[SDKConnectorsharedInstance];}[connector_CallSDKFunc:CreateNSString(type):CreateNSString(jsonpara)];}#ifdefined(__cplusplus)}#endif

这里CallSDKFunc即上述Unity调用SDK的接口,在OC层,直接由SDKConnector类接收,并分发处理。


通用SDK

SDKConnector负责消息的分发

-(void)_CallSDKFunc:(NSString*)type:(NSString*)jsonpara{NSLog(@"[SDK]Receviecmd=%@jsonpara=%@\n",type,jsonpara);if([typeisEqualToString:@"login"]){//登录[LanPlatformlogin:[SDKListenersharedInstance]];}elseif([typeisEqualToString:@"loginout"]){//登出[LanPlatformlogout:[SDKListenersharedInstance]];}elseif([typeisEqualToString:@"switchAccount"]){//切换账号[LanPlatformswitchAccount:[SDKListenersharedInstance]];}elseif([typeisEqualToString:@"pay"]){//充值[LanPlatformpay:[SDKListenersharedInstance]];}

这里根据type类型将消息分发到通用SDK层对应的处理模块,再由通用SDK层去调用平台SDK的API进行具体的处理,注意这里传入了一个实例SDKListener,SDKListener负责接送平台SDK的回应,并将数据发送至Unity侧。


通用SDK层的功能

目前包含以下常见的模块:登录,登出,切换账号,充值,用户中心,用户论坛,用户反馈,防沉迷,实名认证。以及各项游戏数据的上报:选服,进入游戏,创建角色,升级等等。


应用生命周期SDK

SDK中比较特殊的一类,基本上也是所有SDK都需要接入的API是生命周期API,本文处理项对比较特殊一点。

@protocolSDKLifeCycleListener<NSObject>@optional-(void)didFinishLaunching:(NSNotification*)notification;-(void)didBecomeActive:(NSNotification*)notification;-(void)willResignActive:(NSNotification*)notification;-(void)didEnterBackground:(NSNotification*)notification;-(void)willEnterForeground:(NSNotification*)notification;-(void)willTerminate:(NSNotification*)notification;@end//注册生命周期回调函数voidSDKRegisterLifeCycleListener(id<SDKLifeCycleListener>obj){#defineREGISTER_SELECTOR(sel,notif_name)\if([objrespondsToSelector:sel])\[[NSNotificationCenterdefaultCenter]addObserver:obj\selector:sel\name:notif_name\object:nil\];\REGISTER_SELECTOR(@selector(didFinishLaunching:),UIApplicationDidFinishLaunchingNotification);REGISTER_SELECTOR(@selector(didBecomeActive:),UIApplicationDidBecomeActiveNotification);REGISTER_SELECTOR(@selector(willResignActive:),UIApplicationWillResignActiveNotification);REGISTER_SELECTOR(@selector(didEnterBackground:),UIApplicationDidEnterBackgroundNotification);REGISTER_SELECTOR(@selector(willEnterForeground:),UIApplicationWillEnterForegroundNotification);REGISTER_SELECTOR(@selector(willTerminate:),UIApplicationWillTerminateNotification);#undefREGISTER_SELECTOR}

这里定义了一个SDK生命周期监听的协议SDKLifeCycleListener, 以及注册该协议的接口SDKRegisterLifeCycleListener。在App加载的时候,将该监听注册进去,实现该协议的也是SDKListener。

@implementationSDKListener//加载函数,实现在加载该类时,注册生命周期监听函数+(void)load{NSLog(@"[SDK]load\n");SDKRegisterLifeCycleListener([SDKListenersharedInstance]);}


小结

至此,大概介绍了一下所实现的IOS SDK的方法。简而言之,unity通过CallSDKFunc调用通用SDK功能,通用SDK通过SDKConnector分发消息给具体的通用SDK模块,再由平台SDK处理。SDKListener负责接收平台处理的结果和生命周期事件,并将需要的结果返回给Unity。

就目前的实现来看,能够较好的相对解耦游戏与SDK之间的联系,不会因平台的差异性导致游戏代码的频繁改动。当然目前接入的SDK还相对较少还需测试。