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
以上