1. 程式人生 > >unity-與Android互動(unity5、android studio)

unity-與Android互動(unity5、android studio)

建議參考新的方式

  • 使用的是工具是 unity5.4Android Studio 2.0(後面簡稱 AS)
  • 網上找到的教程大部分都是匯出jar給unity呼叫,極少是用AS匯出 aar 包給unity呼叫
  • 用AS匯出jar需要修改一下 build.gradle 檔案,但這裡主要是說匯出 aar包
  • 實現unity掉java裡面的程式碼有兩種方式
  1. 第二種方式,直接使用unity分裝好的類 AndroidJavaClass 等,無需自己打so庫(巨方便,本文將的就是這種)

因為現在eclipse已經停止維護了,官方推薦是用AS來構建Android app,然後匯出 aar 包給unity使用
可以用cocos2dx的方式去理解,也是用一個 MainActivity

去繼承 unity封裝好的 UnityPlayerActivity ,當前應用就是的主執行緒就是跑在 MainActivity

1、使用AS構建一個app工程

  1. File->New->New Project
  2. 包名 Package Name 一定要和unity中打包引數 Bundle Identifier 中的包名一致,這裡用 com.test.yangx
  3. 設定 mini sdk
  4. 選個 Empty Activity
  5. 預設的 MainActivity即可,然後 Finish

2、匯入unity的jar到AS工程中

  • 在unity5中,在
    D:\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

    的路徑下有個 classes.jar
    把這個 classes.jar 丟進AS工程的 libs
    這裡寫圖片描述

  • 工程引用這個 classes.jar

    • 右鍵 工程-> Open Module Settings
    • 這裡寫圖片描述

3、編寫 MainActivity 程式碼

完整程式碼如下

package com.test.yangx;

import android.app.AlertDialog;
import android.os.Vibrator;
import android.os.Bundle;
import android.widget.Toast;

import com.unity3d.
player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; public class MainActivity extends UnityPlayerActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } public String ShowDialog(final String _title, final String _content){ runOnUiThread(new Runnable() { @Override public void run() { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle(_title).setMessage(_content).setPositiveButton("Down", null); builder.show(); } }); return "Java return"; } // 定義一個顯示Toast的方法,在Unity中呼叫此方法 public void ShowToast(final String mStr2Show){ // 同樣需要在UI執行緒下執行 runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(),mStr2Show, Toast.LENGTH_LONG).show(); } }); } // 定義一個手機振動的方法,在Unity中呼叫此方法 public void SetVibrator(){ Vibrator mVibrator=(Vibrator)getSystemService(VIBRATOR_SERVICE); mVibrator.vibrate(new long[]{200, 2000, 2000, 200, 200, 200}, -1); //-1:表示不重複 0:迴圈的震動 } // 第一個引數是unity中的物件名字,記住是物件名字,不是指令碼類名 // 第二個引數是函式名 // 第三個引數是傳給函式的引數,目前只看到一個引數,並且是string的,自己傳進去轉吧 public void callUnityFunc(String _objName , String _funcStr, String _content) { UnityPlayer.UnitySendMessage(_objName, _funcStr, "Come from:" + _content); } }

4、修改 AndroidManifest.xml

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name="com.test.yangx.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>

5、修改 build.gradle

  1. apply plugin: 'com.android.application'
    修改為
    apply plugin: 'com.android.library'
    這樣才能匯出一個 aar

  2. 刪除掉這句程式碼 applicationId "com.test.yangx"

  3. 完整程式碼

    apply plugin: 'com.android.library'
    
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"
    
        defaultConfig {
            minSdkVersion 19
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        compile 'com.android.support:appcompat-v7:23.3.0'
        compile files('libs/classes.jar')
    }
    

6、生產 aar

Build->Build APK
成功會在 app\build\outputs\aar 目錄下出現一個 app-debug.aar
然後用 解壓軟體開啟這個包,刪掉 libs 下的 classes.jar (沒錯,就是之前重unity中拷過來的)
因為unity打包時會重新把自帶的 classes.jar 打進去,如果不刪掉它會打包報錯,衝突

然後這就是最終需要的 aar

然後把這個 aar包 和 AndroidManifest.xml 檔案 丟進unity的 Assets\Plugins\Android 目錄下

7、寫個c# 測試

using UnityEngine;
using System.Runtime.InteropServices;
using UnityEngine.UI;

public class testDll : MonoBehaviour {

    private Text mText;

    void Start()
    {
        //int ret = MyAddFunc(200, 200);
        //Debug.LogFormat("--- ret:{0}", ret);
        mText = GameObject.Find("MsgText").GetComponent<Text>();
    }

    public void MyShowDialog()
    {
        // Android的Java介面  
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        // 引數  
        string[] mObject = new string[2];
        mObject[0] = "Jar4Android";
        mObject[1] = "Wow,Amazing!It's worked!";
        // 呼叫方法  
        string ret = jo.Call<string>("ShowDialog", mObject);
        setMsg(ref ret);
    }

    public void MyShowToast()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.Call("ShowToast", "Showing on Toast");
    }
	
	/// <summary>
    /// 測試 unity->java->unity
    /// </summary>
    public void MyInteraction()
    {
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.Call("callUnityFunc", "U2J2U", "BeCallFunc", "yangx");
    }

    public void BeCallFunc(string _content)
    {
        setMsg(ref _content);
    }

    private void setMsg(ref string _str)
    {
        mText.text = _str;
    }
}

8、打包apk

修改測試引數
要和AS工程中的 Package Name 一致
mini sdk 一致
這裡寫圖片描述

9、done

裝在模擬器上測試以下
這裡寫圖片描述

10、遇到的小坑

  1. unity匯出apk
    File->Build Run
    當匯出apk時,可能遇到下面的問題:

      Unable to find unity activity in manifest. You need to make sure orientation attribute is set to fullSensor manually.
    

    需在AndroidManifest中增加一行:
    <meta-data android:name="unityplayer.UnityActivity" android:value="true" />

  2. 刪除AndroidManifest.xml 中app的主題,否則unity打包apk是關聯的主題會報找不到錯誤,應該是有些庫沒打進去(有待研究)

  3. 刪除生產的arr檔案裡的libs下的classes.jar,這個是之前從u3d中拷過去的,打包時會重新打進去,所以要刪除,不刪除打包會報錯