(轉)Unity3D接入Android第三方SDK流程

一、本例子中使用的Android Studio爲3.2.0版本,Unity爲2018.3.12版本
二、SDK調用Unity3D
1、一般第三方SDK都會有一個暴露給接入方(即Unity3D)的一個接口類,該類中包含了一些SDK功能的各個調用方法,例如下面這個SDK接口類中包含了初始化、登錄、登出三個功能的接入類,裏面的每個方法跟參數都加了註釋;

先看SDK庫工程目錄,mysdk是SDK庫工程,app是一個依賴於SDK庫工程的demo,其中只有一個MainActivity類,便於開發時進行測試,mysdk中只有一個MySDkPlatform類,這個類就是unity接入需要調用的接口類;

 

 

/**
 * 類說明:unity接入SDK的接口類
 */
public class MySDkPlatform {
    
    private static String gameObjectName;//unity傳過來的接收SDK回調的類名,SDK根據此類名調用unity類中的方法
    private static String unityInitCallbackName;//unity傳過來的接收SDK回調的類中的方法,SDK根據此方法名調用unity中的方法
    private String unityLoginCallbackName;//同上
    private String unityLogoutCallbackName;//同上
    
    //單例模式
    public static MySDkPlatform mySDkPlatform;
    public static MySDkPlatform getInstance(){
        if (mySDkPlatform == null) {
            mySDkPlatform = new MySDkPlatform();
        }
        return mySDkPlatform;
    }
 
    //初始化
    public void init(Activity activity){
        System.out.println("調用了mysdk的初始化方法");
        //該方法的三個參數
        //gameObjectName:unity中的gameObject的類名
        //unityInitCallbackName:unity中gameObject綁定的c#腳本里的方法名
        //第三個參數:SDK向unity傳遞的字符串
        UnityPlayer.UnitySendMessage(gameObjectName,unityInitCallbackName,"這是SDK初始化結果回調");
    }
 
    //登錄
    public void login(String arg1){
        System.out.println("調用了mysdk的登錄方法;arg1 = "+arg1);
        UnityPlayer.UnitySendMessage(gameObjectName,unityLoginCallbackName,"這是SDK登錄結果回調");
    }
 
    //登出,靜態,跟以上非靜態方法做不同例子演示
    public static void logout(String arg1){
        System.out.println("調用了mysdk的登出方法");
        UnityPlayer.UnitySendMessage(gameObjectName,unityLogoutCallbackName,"這是SDK登出結果回調");
    }
 
    //拿到unity的類名
    public void setGameObjectName(String gameObjectName){
        this.gameObjectName = gameObjectName;
    }
    //拿到unity接收SDK初始化結果的方法名
    public void setUnityInitCallbackName(String unityInitCallbackName) {
        this.unityInitCallbackName = unityInitCallbackName;
    }
    //拿到unity接收SDK登錄結果的方法名
    public void setUnityLoginCallbackName(String unityLoginCallbackName) {
        this.unityLoginCallbackName = unityLoginCallbackName;
    }
    //拿到unity接收SDK登出結果的方法名
    public void setUnityLogoutCallbackName(String unityLogoutCallbackName) {
        this.unityLogoutCallbackName = unityLogoutCallbackName;
    }
}

 

2、類中的UnityPlayer.UnitySendMessage(gameObjectName,callbackName,arg1)方法是Unity中的一個unity-classes.jar包下的方法,SDK需要引入該包才能編譯,在引入過程中需要注意,因爲unity中已經有這個jar包,SDK庫工程只在編譯的時候需要用到,真正接入的時候,只需要拷貝SDK庫工程生成的aar包即可,不需要把unity-classes.jar編譯進去,否則會報異常,引入unity-classes.jar方法如下:

(1)新建一個unity3dlibs文件夾,保證與工程中的libs不重名,將unity-classes.jar放入該文件夾下

 

 

(2)在工程的build.gradle中加入依賴

//添加一個本地倉庫,並將unity3dlibs目錄作爲倉庫地址
repositories{
    flatDir {
        dirs 'unity3dlibs'
    }
}
 
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    testImplementation 'junit:junit:4.12'
 
    compileOnly files('unity3dlibs/unity-classes.jar')//只在編譯的時候用到
}

 

(3)清單文件;如果SDK中需要在manifest中application根節點下注冊信息,在清單文件中需要編寫以下代碼:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sdk.mysdk">
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
 
        //方式一:SDK的接口類繼承了unity的UnityPlayerActivity,這裏啓動入口填寫SDK的接口類路徑
        //方式二:SDK的接口類沒有繼承unity的UnityPlayerActivity,這裏填寫"com.unity3d.player.UnityPlayerActivity"
        //本例子中使用方式二
        //Unity啓動入口activity
        <activity android:name="com.unity3d.player.UnityPlayerActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

 

清單文件中註冊UnityPlayerActivity是爲了將SDK做成符合Unity接入的plugins,Unity編譯時會將自身生成的manifest和SDK的manifest進行合併,但SDK的manifest優先級比較高,所以需要SDK在manifest中註冊啓動的UnityPlayerActivity。 (注:如果SDK中有Activity並且繼承了UnityPlayerActivity,則啓動應用的main入口需要改爲SDK的Activity)

三、Unity3D調用SDK

1、在Unity中新建一個腳本,調用MySDkPlatform中的方法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class NewBehaviourScript : MonoBehaviour
{
 
    AndroidJavaClass unityPlayer;
    AndroidJavaObject currentActivity;
 
    AndroidJavaClass androidJavaClass;
    AndroidJavaObject androidJavaObject;
 
    // Start is called before the first frame update
    void Start()
    {
        步驟一:拿到接口對象實例
        //方式一
        //通過包名獲取UnityPlayer,目的爲了獲取下面當前activity對象用
        //使用這種方式,SDK的接口類需要繼承UnityPlayerActivity
        //拿到unityPlayer(固定寫法,不用修改),即可調用SDK接口類中的靜態方法,
        unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        //通過unityPlayer獲取當前的activity (注:固定寫法,不用修改),拿到currentActivity,即可調用SDK接口類中的非靜態方法
        currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
 
        //方式二(本例中使用的該方式)
        //獲取SDK的MySDkPlatform類對象,可以直接使用androidJavaClass調用MySDkPlatform的靜態方法
        androidJavaClass = new AndroidJavaClass("com.sdk.mysdk.MySDkPlatform");
        //獲取SDK的MySDkPlatform類中的單例對象,可以直接使用androidJavaObject調用MySDkPlatform中的非靜態方法
        androidJavaObject = androidJavaClass.CallStatic<AndroidJavaObject>("getInstance");
 
        //步驟二:告訴SDK返回參數時要調用Unity的哪一個方法名
        //unity調用SDK的方法,傳入一個參數,該參數爲定義在unity中的方法名,當unity調用SDK的接口,
        //且需要SDK返回參數時,SDK會根據這裏傳入的方法名,調用定義在unity中的方法
        //setGameObjectName爲SDK裏定義的方法名,Main Camera爲untiy當前掛載的腳本
        androidJavaObject.Call("setGameObjectName", "Main Camera");
        //setUnityInitCallbackName爲SDK裏定義的方法名,initCallback爲unity定義的方法名,用於接收SDK回調,下面兩個一樣
        androidJavaObject.Call("setUnityInitCallbackName", "initCallback");
        androidJavaObject.Call("setUnityLoginCallbackName", "loginCallback");
        androidJavaObject.Call("setUnityLogoutCallbackName", "logoutCallback");
 
        //步驟三:調用SDK的接口方法
        //SDK初始化
        Button btn = GameObject.Find("Button").GetComponent<Button>();
        btn.onClick.AddListener(() => 
        {
            Debug.Log("-->初始化");
            //調用初始化方法,傳入當前activity對象(注:這裏的activity參數就是方式一中獲取到的currentActivity)
            androidJavaObject.Call("init", currentActivity);
        });
 
        //登錄
        Button btn2 = GameObject.Find("Button2").GetComponent<Button>();
        btn2.onClick.AddListener(() =>
        {
            androidJavaObject.Call("login", "unity調用了SDK的登錄");
        });
 
        //登出
        Button btn3 = GameObject.Find("Button3").GetComponent<Button>();
        btn3.onClick.AddListener(() =>
        {
            //這裏使用的是androidJavaClass調用的SDK的登出,在SDK接口類中logout方法爲靜態的,                
            //所以這裏使用androidJavaClass類直接調用,而上面登錄方法爲非靜態的,所以使用的是androidJavaObject
            androidJavaClass.Call("logout", "unity調用了SDK的登出");
        });
 
    }
 
    //步驟四:定義unity接收SDK返回參數的方法,這裏的方法名與步驟二中傳入的參數名必須一致
    //SDK初始化後,會調用該方法,參數爲回調結果
    void initCallback(string callback)
    {
        Debug.Log("-->收到SDK初始化的回調:"+callback);
    }
 
    //SDK登錄後,會回調該方法,參數爲回調結果
    void loginCallback(string callback)
    {
        Debug.Log("-->收到SDK登錄的回調:" + callback);
    }
 
    //SDK登出後,會回調該方法,參數爲回調結果
    void logoutCallback(string callback)
    {
        Debug.Log("-->收到SDK登出的回調:" + callback);
    }
 
    // Update is called once per frame
    void Update()
    {
 
    }
}

 

四、打包

1、方式一:SDK打成plugins給Unity(unity版)

把SDK編譯成aar,然後把aar文件、manifest文件放入Unity對應的Assets文件夾下的plugins下的Android下,以及libs下,沒有的文件夾自己新建一個,目錄對應如下:

 

 

Manifest放入Android文件夾下(如上圖)

 

 

SDK的aar包放入libs文件夾下(如上圖)

配置好以上步驟即可開始打包編譯;

2、方式二:Unity導出安卓工程接入SDK(studio版)

這種方式接入更爲簡單,將SDK的aar包拷貝到遊戲導出的studio工程的libs文件夾下,並在gradle中添加aar依賴,然後修改Manifest清單文件即可;(注:SDK工程中unity-classes.jar不需要拷貝進去,untiy導出的studio工程中已經有了這個jar包)。

 

轉載鏈接:https://blog.csdn.net/u010263943/article/details/89366539

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章