unity游戲框架學習-SDK接入


概述鏈接:https://www.cnblogs.com/wang-jin-fu/p/10975660.html

之前概述有說過SDK的大概功能如下:

1.賬號類:創建、登錄、切換

2.充值

3.外部分享如微信、朋友圈、FB等

4.打開外部鏈接,如論壇、社區、反饋等

5.功能類:語音、頭像、埋點

這些功能都是sdk提供的,而我們要做的就是調用sdk的接口(ios的OC接口,android的java接口)

 

一、android和c#交互

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);
}

二、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#一樣,三個參數都是字符串類型!

三、好了。我們知道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#端就完成了,然后后兩端的代碼

四、android端:android端渠道眾多,很有必要跟c#端一樣,每個渠道的接口都實現一個自己的實現類,再用具體的SFMainActivity去管理

android端接sdk有兩種方式,兩種方式的區別可參考:https://blog.csdn.net/yang8456211/article/details/51356193,個人傾向於使用第二種方式,因為很多系統功能在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工程就好了

五、ios端,ios端相對android端沒有這么多渠道,相對會簡單一些,我們只需要把OC的代碼放在Plugins/iOS文件夾就好了(需要注意OC語法的參數類型轉換)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM