unity遊戲框架學習-SDK接入

概述連接: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語法的參數類型轉換)

相關文章
相關標籤/搜索