1. 程式人生 > >通過aar包實現Unity與安卓間的通訊

通過aar包實現Unity與安卓間的通訊

前言:

(最近做了一個虛擬現實和物聯網專案,名字聽起來高大上,其實就是用Unity做個安卓端的虛擬現實場景,然後通過藍芽接收單片機發來的溫度資料,在場景裡顯示。由於Unity引擎本身沒法呼叫藍芽,所以需要通過呼叫安卓aar包來呼叫藍芽,所以涉及到了安卓和unity之間的通訊。)

本例不再展示藍芽的呼叫,只是通過Unity呼叫顯示日期和Toast來示範兩者間的通訊。

網上的教程很多是Eclipse,而講Android studio的很少用aar包,或者教程對應的軟體版本較早。本文旨在總結網上的各種教程,望能給大家一些幫助。

本專案使用的是Unity 5.5.4 和 Android Studio 3.0.1,其它版本方法可能略有不同,但大致相似。

一.Android Studio

1.新建工程

開啟Android Studio,新建工程,如圖所示。

工程設定:命名為UnityAndroid。包名為com.learn.unityandroid(注意都是小寫


再往後一直點Next,最後點Finish,預設建立了MainActivity。


2.修改檔案

點選左上角的選單,選擇Project檢視,可以顯示更加詳細的層級結構。


首先修改app資料夾下的build.gradle檔案。


開啟後修改第一行,將application改為library。(這樣就可以釋出aar包)

刪除掉第6行,否則會報錯。


點選上方的錘子按鈕來Make Project,以測試是否可以釋出aar包。


第一次Make Project的時間會比較長。完成之後,可以看到在app-build-outputs-arr資料夾下已經發布了app-debug.aar,說明打包成功。


3.匯入Unity提供給安卓的classes.jar

在Unity的安裝目錄中找到classes.jar,Windows系統中的安卓包路徑如下(其他系統或Unity版本的路徑請自行搜尋):

E:\Unity 3d\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

(當然,我的Unity是裝在了E盤,大家要換成自己安裝的路徑。找不到的可以右鍵桌面Unity圖示,點選屬性就能看到路徑。)


切記一定要將這個檔案備份,多多益善,不然弄丟了很麻煩的(切身經歷= = 如果匯入的classes.jar和你的Unity版本不對應很有可能出錯,所以網上也不好找,可能要重新下Unity才有。雲盤裡存一份也是個好辦法。)

將這個jar包拖到libs資料夾下,如圖(看見沒,我備份了很多):


右鍵匯入的classes.jar,點選倒數第二項的“Add As Library”以建立依賴關係。



最終的build.gradle如下:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 26
    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation files('libs/classes.jar')
}

4.修改工程以便unity呼叫

修改MainActivity.java檔案。

讓MainActivity繼承UnityPlayerActivity,因為我們將要釋出的Unity安卓端應用本身就是一個Activity。


將圖示一行刪除,因為我們不需要介面。


然後我們寫一個ShowDate方法,呼叫Unity中Main Camera物體上掛的指令碼中的GetDate方法,以更新顯示日期;再寫一個ShowToast方法,來被Unity呼叫,以顯示Toast。

完整程式碼如下:

package com.learn.unityandroid;

import android.os.Bundle;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import java.text.SimpleDateFormat;

public class MainActivity extends UnityPlayerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    public void ShowDate(){
        SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String date = sDateFormat.format(new java.util.Date());
        UnityPlayer.UnitySendMessage("Main Camera","GetDate",date);
    }

    public void ShowToast(String str){
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    }
}

將res資料夾下的layout資料夾刪除,因為我們不需要介面。


同理,再將values資料夾下的styles.xml檔案刪除。


開啟下邊的AndroidManifest檔案。


可以看見此時已經顯示紅色,表明有錯誤。


把theme修改成安卓自帶的主題就可以了:


將activity的name改為如圖所示,以防止報錯。


再新增一行meta-data資訊,否則釋出的apk是無法執行的(別問我怎麼知道的……)


最終的AndroidManifest如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.learn.unityandroid">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.NoTitleBar">
        <activity android:name="com.learn.unityandroid.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
        </activity>
    </application>

</manifest>

點選小錘子按鈕來Make Project


右鍵剛剛釋出的aar包。


點選下方的Show In Explorer,顯示具體檔案。雙擊開啟。

在壓縮包裡將libs資料夾下的classes.jar刪除,因為後期Unity呼叫的時候會自動加入。

       

好了,我們的安卓包已經制作完成,接下來就是Unity方面的事了。

二、Unity

1.新建工程

新建工程,命名為UnityAndroid(可以隨便起名)。
在場景中建立Canvas畫布,然後新增Text和Button。按ctrl+s儲存場景,命名為main。
scene中檢視如下:
在File - Build Setting裡匯入main場景,並且將平臺切換成安卓。

2.建立指令碼並繫結

在Main Camera上掛載新建的名為Main Camera的指令碼。
開啟MainCamera指令碼進行編輯,最終程式碼如下:
using UnityEngine;
using UnityEngine.UI;

public class MainCamera : MonoBehaviour
{
    //獲取日期顯示檔案的text元件
    public Text dateText;

    private AndroidJavaObject mainActivity;

    //每幀呼叫安卓的ShowDate函式,再通過安卓呼叫下方的GetDate函式。
    void Update()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        mainActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");

        mainActivity.Call("ShowDate");
    }

    //安卓呼叫,更新日期文字的顯示
    public void GetDate(string str)
    {
        dateText.text = str;
    }

    //按鈕呼叫安卓顯示Toast
    public void ShowToastButton()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        mainActivity = jc.GetStatic<AndroidJavaObject>("currentActivity");

        mainActivity.Call("ShowToast", "Unity呼叫安卓Toast了");
    }
}
將DateText拖拽到Main Camera指令碼來繫結,再將按鈕繫結ShowToastButton事件。

     

3.匯入aar包和Manifest檔案

在Project面板中,在Assets根目錄下新建Plugins資料夾,再在其下新建Android資料夾。


將我們之前製作好的aar包和AndroidManifest檔案拖拽到剛剛建好的Android資料夾下。

    

4.修改player settings併發布apk

將預設旋轉設為Landscape Right,即為鎖定右向橫屏。

   

bundle identifier修改為安卓的ID名,將Minimum API Level設為manifest裡的最低版本。

 

注意這時是無法直接執行進行模擬的,我們需要在真機上執行。可以接上手機開啟除錯模式,然後點選Build & Run;也可以釋出apk,然後傳到手機上安裝執行。

三、執行效果

最終執行效果如下圖所示,上方文字實時顯示日期,點選“顯示Toast”按鈕顯示了Toast:


本文到此結束, 有問題請在下方留言,我會盡量及時回覆。謝謝觀看。