出海游戏开发中,sdk接入是必不可少的,sdk接入包括:
1.账号类:创建、登录、切换 Facebook SDK, AppleId SDK
2.充值 ,unity IAP,如果接入其他平台,比如亚马逊,需要调用这些平台的接口
3.外部分享如微信、朋友圈、FB等
4.打开外部链接,如helpshift ,广告平台
5.功能类:语音、头像、埋点
这些功能都是sdk提供的,而我们要做的就是调用sdk的接口(有的有Unity SDK,有的是原生接口,ios的OC接口,android的java接口) 如果有Unity SDK ,直接导入到Unity 工程,像调用正常的C#方法一样调用即可。
一、android和c#交互
1.c#调用android方法,如下,使用 AndroidJavaClass获取AndroidJavaObject对象,在通过AndroidJavaObject调用java方法。最常用的是AndroidJavaObject的Call方法,unity文档:http://docs.unity3d.com/ScriptReference/AndroidJavaObject.html 这个Call是支持多参数的,第一个参数必须是方法名,第二个开始则是各种参数。如果有返回值则需要使用泛型版本Call。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 using UnityEngine; /// <summary> /// Android帮助库 /// 提供unity对android端的调用,属性的get和set麻烦封装成方法 /// </summary> public class AndroidHelper { const string AndroidMainActivity = "com.unity3d.player.UnityPlayer"; static AndroidJavaObject ms_MainActivity; public static AndroidJavaObject MainActivity { get { if (ms_MainActivity == null) { AndroidJavaClass jc = new AndroidJavaClass (AndroidMainActivity); if (jc != null) { ms_MainActivity = jc.GetStatic<AndroidJavaObject> ("currentActivity"); } } return ms_MainActivity; } } #region MainActivity的非静态方法 public static void Call(string method) { MainActivity.Call(method); } public static void Call(string method, object[] args) { MainActivity.Call(method, args); } public static void Call(string method, bool val) { MainActivity.Call(method, new object[] { val }); } public static void Call(string method, string val) { MainActivity.Call(method, new object[] { val }); } public static string CallWithReturn(string method) { string result = ""; AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); result = jo.Call<string>(method); return result; } #endregion #region MainActivity的静态方法 public static void CallStatic(string method) { MainActivity.CallStatic(method); } public static void CallStatic(string method, string val) { MainActivity.CallStatic(method, new object[] { val }); } public static string CallStaticWithReturn(string val) { string result = ""; AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); result = jo.CallStatic<string>(val); return result; } #endregion }
2.Java回调unity,public static void UnitySendMessage(String var0, String var1, String var2) ,第一个参数为unity中的一个gameobject名称,第二个参数为这个gameobject身上捆绑的脚本中的一个方法,而第三参数是这个对应方法上的参数
1 2 3 4 5 6 7 8 9 10 public static final String UNITY_HANDLER = "SDKMsgHandler"; ** * 向Unity传送 * @param arg1 函数名 * @param arg2 参数 */ public static void UnitySendMessage(String arg1, String arg2) { UnityPlayer.UnitySendMessage(UNITY_HANDLER, arg1, arg2); }
二、ios和c#的交互,可以参照官网:https://docs.unity3d.com/Manual/PluginsForIOS.html, 你需要把你的oc代码放在Plugins/iOS文件夹下才能正确调用到OC的代码
c#调用ios:c#端
1 2 3 4 5 6 7 8 9 10 11 [DllImport("__Internal")] private static extern string U3dGetAvailableDiskSize(); /// <summary> /// 获取磁盘空间 /// </summary> public long GetAvailableDiskSize() { string size = U3dGetAvailableDiskSize(); return long.Parse(size); }
OC端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 char* _MakeStringCopy( const char* string) { if (NULL == string) { return NULL; } char* res = (char*)malloc(strlen(string)+1); strcpy(res, string); return res; } const char* U3dGetAvailableDiskSize() { struct statfs buf; long long freespace = -1; if(statfs("/var", &buf) >= 0) { freespace = (long long)(buf.f_bsize * buf.f_bfree); } NSString *_msg = [NSString stringWithFormat:@"%lld", freespace]; return _MakeStringCopy([_msg UTF8String]); }
2.OC回调unity:
UnitySendMessage(“GameObjectName1”, “MethodName1”, “Message to send”); 参数1:gameobject名字;参数2:回调函数的名字;参数3:参数。同android开发中java回调c#一样,三个参数都是字符串类型!
三、好了。我们知道unity跟ios\android怎么交互了,可以开始设计我们的接口了,首先在c#端,我们需要区分三种平台,ios\android\unity editor三种平台,我们不可能像下面这么写,几十个接口如果都这么写,会原地爆炸的,所以我们需要用的接口来规范我们的代码
1 2 3 4 5 6 7 8 9 if(platform == ios) { //xxxx }else if(paltform == android) { //xxxx }else if(platform == editor){ //xxxx }
1.首先我们需要有一个接口类:
1 2 3 4 5 6 7 8 public interface SDKInterface { /** 登录 **/ void Login(); /** 打开SDK用户中心界 **/ void ShowUserCenter(); }
2.我们需要有每个平台的具体实现类(其实就是ios调用OC,android调用Java,editor平台啥也不做),如下所示,U3dLogin\ShowUserCenter是Ios、android两端的实现代码,这里就不上了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #if UNITY_ANDROID public class AndroidSDK : SDKInterface { /// <summary> /// 登录 /// </summary> public void Login() { Call("U3dLogin"); } /// <summary> /// 打开SDK用户中心界 /// </summary> public void ShowUserCenter() { Call("U3dShowUserCenter"); } } #endif
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #if UNITY_IOS public class IOSSDK : SDKInterface { [DllImport("__Internal")] private static extern void U3dLogin(); [DllImport("__Internal")] private static extern void U3dShowUserCenter(); /// <summary> /// 登录 /// </summary> public void Login() { U3dLogin(); } /// <summary> /// 打开SDK用户中心界 /// </summary> public void ShowUserCenter() { U3dShowUserCenter(); } } #endif
1 2 3 4 5 6 public class EmptySDK : SDKInterface { public void Login() { } public void ShowUserCenter() { } }
3.一个接受两端回调消息的类,ios\android共用一个就好了,该类会在管理类里面初始化
1 2 3 4 5 6 7 8 9 10 11 public class SDKMsgHandler : MonoBehaviour { /// <summary> /// 登录回调 /// </summary> /// <param name="msg">msg</param> public void LoginNotification(string msg) { Debug.Log("登录回调:" + msg); } }
4.我们需要一个管理类,来确定具体是调用哪一个接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class SDKModule : ModuleBase { public SDKModule () { #if UNITY_EDITOR || GUIDE _sdk = new EmptySDK (); #elif UNITY_IOS _sdk = new IOSSDK(); #elif UNITY_ANDROID _sdk = new AndroidSDK(); #else _sdk = new EmptySDK(); #endif GameObject go = new GameObject ("SDKMsgHandler"); GameObject.DontDestroyOnLoad (go); go.AddComponent<SDKMsgHandler> (); } /// <summary> /// 登录 /// </summary> public void Login () { Debug.Log("Login c"); _sdk.Login (); } /// <summary> /// 打开SDK用户中心界 /// </summary> public void ShowUserCenter () { Debug.Log("ShowUserCenter c"); _sdk.ShowUserCenter (); } }
至此,c#端就完成了。