前言:
(最近做了一个虚拟现实和物联网项目,名字听起来高大上,其实就是用Unity做个安卓端的虚拟现实场景,然后通过蓝牙接收单片机发来的温度数据,在场景里显示。由于Unity引擎本身没法调用蓝牙,所以需要通过调用安卓aar包来调用蓝牙,所以涉及到了安卓和unity之间的通信。)
本例不再展示蓝牙的调用,只是通过Unity调用显示日期和Toast来示范两者间的通信。
网上的教程很多是Eclipse,而讲Android studio的很少用aar包,或者教程对应的软件版本较早。本文旨在总结网上的各种教程,望能给大家一些帮助。
本项目使用的是Unity 5.5.4 和 Android Studio 3.0.1,其它版本方法可能略有不同,但大致相似。
打开Android Studio,新建工程,如图所示。
工程设置:命名为UnityAndroid。包名为com.learn.unityandroid(注意都是小写)
再往后一直点Next,最后点Finish,默认创建了MainActivity。
点击左上角的菜单,选择Project视图,可以显示更加详细的层级结构。
首先修改app文件夹下的build.gradle文件。
打开后修改第一行,将application改为library。(这样就可以发布aar包)
删除掉第6行,否则会报错。
点击上方的锤子按钮来Make Project,以测试是否可以发布aar包。
第一次Make Project的时间会比较长。完成之后,可以看到在app-build-outputs-arr文件夹下已经发布了app-debug.aar,说明打包成功。
在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')
}
修改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如下:
点击锤子按钮来Make Project
右键刚刚发布的aar包。
点击下方的Show In Explorer,显示具体文件。双击打开。
在压缩包里将libs文件夹下的classes.jar删除,因为后期Unity调用的时候会自动加入。
好了,我们的安卓包已经制作完成,接下来就是Unity方面的事了。
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("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("currentActivity");
mainActivity.Call("ShowToast", "Unity调用安卓Toast了");
}
}
在Project面板中,在Assets根目录下新建Plugins文件夹,再在其下新建Android文件夹。
将我们之前制作好的aar包和AndroidManifest文件拖拽到刚刚建好的Android文件夹下。
将默认旋转设为Landscape Right,即为锁定右向横屏。
将bundle identifier修改为安卓的ID名,将Minimum API Level设为manifest里的最低版本。
注意这时是无法直接运行进行模拟的,我们需要在真机上运行。可以接上手机打开调试模式,然后点击Build & Run;也可以发布apk,然后传到手机上安装运行。
最终运行效果如下图所示,上方文字实时显示日期,点击“显示Toast”按钮显示了Toast:
谢谢观看。