概述連接:http://www.javashuo.com/article/p-nggymcxb-bw.htmlhtml
以前概述有說過SDK的大概功能以下:java
1.帳號類:建立、登陸、切換android
2.充值ios
3.外部分享如微信、朋友圈、FB等c#
4.打開外部連接,如論壇、社區、反饋等微信
5.功能類:語音、頭像、埋點函數
這些功能都是sdk提供的,而咱們要作的就是調用sdk的接口(ios的OC接口,android的java接口)spa
1、android和c#交互.net
1.c#調用android方法,以下,使用 AndroidJavaClass獲取AndroidJavaObject對象,在經過AndroidJavaObject調用java方法。最經常使用的是AndroidJavaObject的Call方法,unity文檔:http://docs.unity3d.com/ScriptReference/AndroidJavaObject.html
這個Call是支持多參數的,第一個參數必須是方法名,第二個開始則是各類參數。若是有返回值則須要使用泛型版本Call<Type>。設計
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身上捆綁的腳本中的一個方法,而第三參數是這個對應方法上的參數
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); }
2、ios和c#的交互,能夠參照官網:https://docs.unity3d.com/Manual/PluginsForIOS.html,你須要把你的oc代碼放在Plugins/iOS文件夾下才能正確調用到OC的代碼
c#調用ios:c#端
[DllImport("__Internal")] private static extern string U3dGetAvailableDiskSize(); /// <summary> /// 獲取磁盤空間 /// </summary> public long GetAvailableDiskSize() { string size = U3dGetAvailableDiskSize(); return long.Parse(size); }
OC端
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#同樣,三個參數都是字符串類型!
3、好了。咱們知道unity跟ios\android怎麼交互了,能夠開始設計咱們的接口了,首先在c#端,咱們須要區分三種平臺,ios\android\unity editor三種平臺,咱們不可能像下面這麼寫,幾十個接口若是都這麼寫,會原地爆炸的,因此咱們須要用的接口來規範咱們的代碼
if(platform == ios) { //xxxx }else if(paltform == android) { //xxxx }else if(platform == editor){ //xxxx }
1.首先咱們須要有一個接口類:
public interface SDKInterface { /** 登陸 **/ void Login(); /** 打開SDK用戶中心界 **/ void ShowUserCenter(); }
2.咱們須要有每一個平臺的具體實現類(其實就是ios調用OC,android調用Java,editor平臺啥也不作),以下所示,U3dLogin\ShowUserCenter是Ios、android兩端的實現代碼,這裏就不上了
#if UNITY_ANDROID public class AndroidSDK : SDKInterface { /// <summary> /// 登陸 /// </summary> public void Login() { Call("U3dLogin"); } /// <summary> /// 打開SDK用戶中心界 /// </summary> public void ShowUserCenter() { Call("U3dShowUserCenter"); } } #endif
#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
public class EmptySDK : SDKInterface { public void Login() { } public void ShowUserCenter() { } }
3.一個接受兩端回調消息的類,ios\android共用一個就行了,該類會在管理類裏面初始化
public class SDKMsgHandler : MonoBehaviour { /// <summary> /// 登陸回調 /// </summary> /// <param name="msg">msg</param> public void LoginNotification(string msg) { Debug.Log("登陸回調:" + msg); } }
4.咱們須要一個管理類,來肯定具體是調用哪個接口
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#端就完成了,而後後兩端的代碼
4、android端:android端渠道衆多,頗有必要跟c#端同樣,每一個渠道的接口都實現一個本身的實現類,再用具體的SFMainActivity去管理
android端接sdk有兩種方式,兩種方式的區別可參考:http://www.javashuo.com/article/p-rcxsroec-mk.html,我的傾向於使用第二種方式,由於不少系統功能在unity很差實現,但在android端卻很好實現,如推送、谷歌支付等
1.將sdk的代碼打成jar\aar的包導入到unity.
android studio(as)導出aar可參考:https://www.jianshu.com/p/b059e84e85d1
android studio(as)導出jar可參考:https://www.jianshu.com/p/8256c0da444a
2.將unity導出到android studio,在使用as打apk
(1)將unity導出的項目,刪除其中的src/main文件夾下的assets\jinLibs\res三個文件夾,拷貝該工程做爲咱們的as工程
(2)新建一個java類SFMainActivity,該類繼承自UnityPlayerActivity,該類的職責相似於前面的SDKModule,負責sdk的初始化(例如語言、版本等須要通知渠道方的)和unity接口的封裝,前面AndroidSDK即調用的是這個類的方法
(3)新建一個sdk的接口類,該類和SDKInterface接口一致,新建不一樣渠道的實現類,實現類繼承自接口類,完成具體的sdk功能
(4)打包的時候只須要把第一步刪除的內容拷貝到咱們的備份as工程就行了
5、ios端,ios端相對android端沒有這麼多渠道,相對會簡單一些,咱們只須要把OC的代碼放在Plugins/iOS文件夾就行了(須要注意OC語法的參數類型轉換)