Unity和Android相互調(diào)用的方式(aar)

1.準(zhǔn)備階段

AndroidStudio3.2.1

Unity2018.4.21f1

gradle4.6

AndroidSDK 29

2.創(chuàng)建Android Module

創(chuàng)建AndroidProject,項(xiàng)目名隨便寫、包名正式一點(diǎn),不重要
比如這里包名我用的com.pistachios.test

一路Next,選擇EmptyActivity

新建一個(gè)Module,選擇AndroidLibrary

名稱取個(gè)正規(guī)點(diǎn)的名字,這個(gè)名字跟包名在Unity中會(huì)用到
這里我用的UnityAndroidModule
Module會(huì)幫我自動(dòng)生成包名com.pistachios.test.unityandroidmodule

Gradle會(huì)在如下位置報(bào)錯(cuò):

implementation'com.android.support:appcompat-v7:29.+'

將v7:29.+改為v7:+即可

3.導(dǎo)入unity的jar

從Unity安裝路徑下

\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar

拿到classes.jar,拷貝到自己在AndroidStudio中創(chuàng)建的Module下的libs文件,為了區(qū)分,可以將classes.jar改個(gè)名,比如unity.jar

然后打開File->ProjectStructure,或Ctrl+Shift+Alt+S

選擇自己創(chuàng)建的Module,點(diǎn)擊dependencies,點(diǎn)擊+,選擇JarDependency,在彈出的對(duì)話框中選擇自己導(dǎo)入的從unity復(fù)制進(jìn)來的jar文件

進(jìn)入自建Module的build.gradle

注釋掉implementation fileTree(include: ['*.jar'], dir: 'libs')

修改implementation files('libs/unity.jar')為compileOnly files('libs/unity.jar')

以上對(duì)gradle的操作,是為了防止打包后將Unity的jar打入aar,在Unity打包成apk時(shí)會(huì)產(chǎn)生沖突錯(cuò)誤

4.Android編寫調(diào)用代碼

在[Module] / src / main / java / [包名] 下創(chuàng)建java的Class

比如我們命名為AndroidLib.java,這個(gè)也可以起一個(gè)正規(guī)點(diǎn)的名字

然后寫一些調(diào)用代碼,反射獲取UnityPlayerActivity,后調(diào)用其他Android原生代碼,如:


package com.pistachios.test.unityandroidmodule;
import android.app.Activity;
import android.content.Context;
import android.os.Vibrator;
import android.util.Log;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;

public class AndroidLib{
    private Activity unityActivity;
    private Context context;

    public void init(){
        getActivity();
    }

    private Activity getActivity(){
        if(null == unityActivity) {
            try {
                Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
                Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);
                unityActivity = activity;
                context = activity;
            } catch (ClassNotFoundException e) {
                System.out.println(e.getMessage());
            } catch (IllegalAccessException e) {
                System.out.println(e.getMessage());
            } catch (NoSuchFieldException e) {
                System.out.println(e.getMessage());
            }
        }
        return unityActivity;
    }

    public void testInAndroid(final String content) {
        Log.i("Android", "testInAndroid");
        Toast.makeText(unityActivity, content,Toast.LENGTH_SHORT).show();
    }

    public void testCallback(){
        Log.i("Android", "testCallback");
        UnityPlayer.UnitySendMessage("AndroidRecall", "AndroidCallback", "arg1");
    }

    public void testSetVibrator(){
        Vibrator mVibrator = (Vibrator) unityActivity.getSystemService(Context.VIBRATOR_SERVICE);
        mVibrator.vibrate(new long[]{200, 2000, 2000, 200, 200, 200}, -1);
    }

}

init方法需要Unity盡早調(diào)用。
testCallback方法會(huì)調(diào)用Unity場(chǎng)景中名為AndroidRecall的物體上掛載腳本中的AndroidCallback方法,參數(shù)是arg1,具體調(diào)用可以查一下,文檔很多
由于最后一個(gè)SetVibrator()中調(diào)用了關(guān)于震動(dòng)的方法,需要在AndroidManifest.xml中添加關(guān)于震動(dòng)的權(quán)限,理論上在寫的時(shí)候IDE會(huì)自動(dòng)提示添加的
<uses-permission android:name="android.permission.VIBRATE" />

5.導(dǎo)出aar

Build->Make Module '[你的module名稱]'
導(dǎo)出后如果不放心,可以打開aar看一眼是否lib中存在unity的jar,如果存在就手動(dòng)刪除

6.Unity端調(diào)用

拿到aar后拷貝到Unity端的Assets/Plugins/Android目錄下
核心調(diào)用代碼如下

//AndroidLibBridge.cs
    private AndroidJavaObject _androidObject;
    private void InitAndroidBridge()
    {
        //這里填寫Module下的類名
        //module包名我用的com.pistachios.test.unityandroidmodule
        //類名我用的AndroidLib
        //所以這里傳入的是com.pistachios.test.unityandroidmodule.AndroidLib
        _androidObject = new AndroidJavaObject("com.pistachios.test.unityandroidmodule.AndroidLib");

        //這里的init是在Android端定義的init方法
        _androidObject.Call("init");
    }

    private void TestInAndroid()
    {
        Debug.Log("TestInAndroid");
        _androidObject.Call("testInAndroid", "This is a Unity Content!");
    }

    private void TestCallAndroid2Unity()
    {
        Debug.Log("TestCallAndroid2Unity");
        _androidObject.Call("testCallback");
    }

    public void CallSetVibrator()
    {
        _androidObject.Call("testSetVibrator");
    }
//AndroidLibCallback.cs
    public void AndroidCallback(params string[] args)
    {
        GameObject cubeGo = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cubeGo.transform.position = Vector3.zero;
        cubeGo.transform.localScale = Vector3.one;
    }

可以將androidObject 對(duì)象緩存起來,寫個(gè)按鈕模擬下調(diào)用就好
TestInAndroid會(huì)看到安卓的Toast
TestCallAndroid2Unity會(huì)調(diào)用Android的方法testCallback再調(diào)用Unity的方法AndroidCallback,會(huì)在(0,0,0)點(diǎn)生成個(gè)沒有材質(zhì)的方塊
CallSetVibrator會(huì)使手機(jī)震動(dòng)
注!如果想測(cè)試TestCallAndroid2Unity方法,需要按照上面說的,在場(chǎng)景中創(chuàng)建一個(gè)名為AndroidRecall的物體,物體上掛AndroidLibCallback.cs

以上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容