實現Unity和Android進行交互

1.背景

這里的實現是在Android studio 2.2和Unity 5.4上。本人是Android開發者,因為公司的業務需求需要與unity進行對接。那么暴露出來最需要解決的問題就是android上實現的方法和unity腳本上實現的方法如何進行相互的調用。在解決該問題的過程中,找了很多的教程以及google了很多其中問題的解決方法。下面就是我整理出來的一些操作步驟和問題的解決方式。

2 Android上的操作

2.1 新建Android項目

首先新建一個android項目,file-->new-->new project,這里新建項目的名稱為UnityAndroid,包名為cn.unity.android,一直點擊next到finish就ok了。

新建android項目

??然后將項目切換成project的格式,打開app目錄下的build.gradle文件,將apply plugin: 'com.android.application',改成apply plugin: 'com.android.library',因為android studio只有在這種格式下才可以導出unity需要使用的aar或者jar文件。然后刪除defaultConfig下的applicationId,去掉默認的dependencies下的
compile 'com.android.support:appcompat-v7:25.0.0'的引入,因為這里不需要用到它,而且這個包包含了很多的資源文件我們是用不到的,最后格式為。
build.gradle文件

project格式

??接下來我們需要修改AndroidManifest文件和res文件,首先刪除values下的style.xml文件,因為這里面默認包含的是之前刪除的com.android.support:appcompat-v7:25.0.0包里面的主題。然后修改AndroidManifest文件中application下的theme為android自帶的主題。同時將<activity android:name=".MainActivity">修改為<activity android:name="cn.unity.android.MainActivity">,防止在unity中導出的app與AndroidManifest中的包名不一致產生的問題。
??然后添加<meta-data>信息,否則在 Unity 導出 APK 時會報找不到manifest 文件的錯誤信息

<meta-data android:name="unityplayer.UnityActivity" android:value="true" /> 

最后得到的AndroidManifest和res的格式如下

修改后的AndroidManifest
res目錄結構

2.2 引入unity的 classes.jar包

找到unity的classes.jar包。windows下和mac下包的路徑分別為
C:\ProgramFiles\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\classes.jar
/Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Classes\classes.jar
??將其拷貝到UnityAndroid項目app目錄下的libs目錄下,然后進行導入,導入之后可以發現在build.gradle中就有他的引入了。

導入classes.jar
classes.jar導入成功

2.3 為unity寫android方法

首先需要讓MainActivity繼承UnityPlayerActivity,因為unity導出的app的視圖展示需要在UnityPlayerActivity下。假如MainActivity繼承的是Activity,那么顯示的就是Android自己的界面。在這里我們寫兩個方法,一個是彈出Toast通知,一個是獲取當前時間,具體代碼如下。

package cn.unity.android;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;

import com.unity3d.player.UnityPlayerActivity;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class MainActivity extends UnityPlayerActivity {

    private Toast mToast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    public void showToast(final String text) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {

            public void run() {
                if (mToast == null) {
                    mToast = Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT);
                } else {
                    mToast.setText(text);
                }
                mToast.show();
            }
        });
    }

    public String getNowTime() {
        long time = System.currentTimeMillis();
        return new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.CHINESE).format(new Date(time));
    }
}

接下來需要導出aar包和jar包,為接下來unity調用提供方法。點擊build-->build apk,然后在app-->build-->outputs-->aar目錄下的到app-debug.aar文件

app-debug.aar

??將app-debug.aar文件解壓,得到根目錄下的classes.jar文件,請注意這個classes.jar文件并不是最開始從unity中導入到android的classes.jar文件,而且你寫的android代碼的class文件的壓縮包(可以解壓看看里面實際的內容)。之后unity所需要使用的是res文件夾下的文件,classes.jar(android的)和AndroidManifest文件。

解壓后的文件

(ps:理論上來說現在版本的unity是直接可以使用android的aar包的,但是博主在實際使用過程中一直會有問題,所以這邊所使用的還是jar包和res文件的形式,如果有小伙伴使用aar成功的話請告知博主)

3 Unity上的操作

3.1 創建Unity項目

打開unity,創建項目名稱為UnityDemo,layout的格式改為2by3,project下修改為One column layout(純粹是個人喜歡這種布局的方法,當然你也可以用其他的)。

One column layout
2by3

??往unity添加一個canvas(畫布),設置render mode為screen space camera(跟隨相機的模式),然后設置ui scale mode 為scale with screen camera 并設置x,y為600和400。

添加canvas

??往canvas中添加一個text和一個button,并調整他們的大小和位置,用于之后的事件操作和顯示。

text
最終的ui顯示

??然后將我們之前導出的jar和res文件拷貝到Plugins/Android文件夾下。

導入文件

3.2 編寫unity腳本

新建一個AndroidControl的C#腳本,并將其掛載到Canvas對象上。(直接通過鼠標左鍵拖動到Canvas上)。打開腳本,在OnStart()方法中獲取android的MainActivity對象。

private AndroidJavaObject jo;
    void Start ()
    {
        //獲取Android的Java接口  
        AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");  
        jo = jc.GetStatic<AndroidJavaObject> ("currentActivity"); 
    }

首先獲取unityPlayer實例,每個unity app在啟動的時候都會有一個unityPlayer實例。通過獲取該實例里面currentActivity對象,其實就是我們的MainActivity實例。我們可以在android studio中查看源碼的方式知道為什么是獲取這個currentActivity。

UnityPlayer

??創建方法ShowAndroidTime來獲取系統時間并進行顯示。

public void  ShowAndroidTime ()
    {
        string time = jo.Call<string> ("getNowTime");
        jo.Call ("showToast", new object[]{ time });
    }

首先調用MainActivity中的getNowTime方法得到時間,然后在調用showToast方法讓時間Toast出來。接下來是要對button設置點擊事件去調用這個ShowAndroidTime方法。選中button,然后砸onclick點擊+。由于我們的腳本是掛在到Canvas上的,所以需要選擇canvas對面里面的AndroidControl腳本的ShowAndroidTime方法。

添加點擊事件

3.3 導出Android app

將scene保存,然后點擊file-->build settings,選擇platform為android,然后點擊switch platform,同時將要導出的scene add進來。

settings

??點擊player settings進行一些android 導出的設置。在這里我們設置apk的名稱為UnityDemo,顯示為橫屏,設置包名為cn.unity.demo,要注意的是把install location設置為Automatic,否則apk會安裝失敗,同時需要指定apk的簽名。

名稱
橫屏
包名
簽名

最后點擊build導出apk,如果已經連接上android設備的話,可以直接build and run進行導出和啟動。

導出apk

看下我們最終實現的效果


效果

4 Android上調用Unity的方法

以上我們實現了unity上調用android的方法,那么android上如何調用unity的方法呢,我們先回到unity的AndroidControl腳本。添加方法OnTimeResult,注意在這里需要導入UnityEngine.UI包usingUnityEngine.UI;

public void OnTimeResult (string result)
    {
        Text text = GameObject.Find ("TimeShow").GetComponent<Text> ();
        text.text = result;
    }

上面代碼的意思是獲取名稱為TimeShow的對象,然后將該對象上的Text腳本的文本改為得到的result。所以我們需要將之前的Text對象名稱改為TimeShow

修改名稱

??回到android的MainActivity,修改方法showToast,讓Toast時間的時候同時調用OnTimeResult方法修改text的文本。

public void showToast(final String text) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {

            public void run() {
                if (mToast == null) {
                    mToast = Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT);
                } else {
                    mToast.setText(text);
                }
                mToast.show();
                UnityPlayer.UnitySendMessage("Canvas","OnTimeResult",text);
            }
        });
    }

UnityPlayer.UnitySendMessage("Canvas","OnTimeResult",text);方法的意思是調用名稱為Canvas對象上的OnTimeResult方法,傳入的參數為text。這樣我們的操作就完成了,重復上面的操作,我們來看下效果。

效果

5 使用adb logcat查看日志

上述的過程已經完成了unity和android之間的方法的相互調用,但是問題來了。這樣沒有出錯還好,一旦出錯,如何查看日志呢。這個時候我們可以使用android的adb工具了。(使用之前我們需要配置環境變量,至于如何配置adb的環境,這里就不多闡述了)。
??在unity的腳本代碼中,增加日志的輸出。并導出apk

public void OnTimeResult (string result)
    {
        Text text = GameObject.Find ("TimeShow").GetComponent<Text> ();
        text.text = result;
        Debug.Log ("UnityTime-->"+result);
    }

打開控制臺,輸入adb logcat -s Unity,然后打開apk,點擊button,這個時候就可以看到剛剛的日志輸出了。(ps:更多的adb logcat的語法可以自己百度google查看)

logcat
logcat輸出

6 后續:

至此,一個比較完整的unity和android交互的步驟和如何查看日志就已經完成了。如果大家在學習使用的過程有什么問題或者有什么更好的方法方式歡迎一起交流。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容