Unity和Android交互案

来源:互联网 发布:淘宝店花呗怎么开通 编辑:程序博客网 时间:2024/05/18 01:39

转自:http://www.jianshu.com/p/7e46fe7485bb,本文有本人学习时轻微修改,请点击链接查看原文,尊重楼主版权。

本文讲解了Unity和Android交互,相互调用函数,传参,获取返回值,还是较全的。本文使用的是Android Studio2.1.2(以下简称AS)和Unity5.4.楼主是做安卓的,而本人是做Unity的,所以安卓部分我也是跟楼主现学现用,说不清的地方勿怪。


Unity和Android交互


1.新建Android项目


1/ 首先打开AS新建一个android项目,file-->new-->new project,这里新建项目的名称为UnityAndroid1,包名为com.eam.unityandroid1,一直点击next到finish就ok了。

2/ 然后将项目切换成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'的引入,因为这里不需要用到它,而且这个包包含了很多的资源文件我们是用不到的,最后格式为:

apply plugin: 'com.android.library'android {    compileSdkVersion 25    buildToolsVersion "25.0.3"    defaultConfig {        minSdkVersion 15        targetSdkVersion 25        versionCode 1        versionName "1.0"    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }}dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'}
3/ 接下来我们需要修改AndroidManifest文件和res文件:

首先删除values下的style.xml文件,因为这里面默认包含的是之前删除的com.android.support:appcompat-v7:25.0.0包里面的主题。

然后修改AndroidManifest文件中application下的theme为android自带的主题: "@android:style/Theme.NoTitleBar"。

同时将<activity android:name=".MainActivity">修改为<activity android:name="com.eam.unityandroid1.MainActivity">,防止在unity中导出的app与AndroidManifest中的包名不一致产生的问题。
然后添加<meta-data>信息,否则在 Unity 导出 APK 时会报找不到manifest 文件的错误信息:

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


最后得到的AndroidManifest格式如下:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.eam.unityandroid1"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="15"        android:targetSdkVersion="25" />    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@android:style/Theme.NoTitleBar" >        <activity android:name="com.eam.unityandroid1.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>

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目录下,然后右击选择Add As Library进行导入,导入之后可以发现在build.gradle中就有他的引入了。

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


3. 为unity写android方法


首先需要让MainActivity继承UnityPlayerActivity,因为unity导出的app的视图展示需要在UnityPlayerActivity下。假如MainActivity继承的是Activity,那么显示的就是Android自己的界面。在这里我们写两个方法,一个是弹出Toast通知,一个是获取当前时间,具体代码如下。

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文件解压,得到根目录下的classes.jar文件,请注意这个classes.jar文件并不是最开始从unity中导入到android的classes.jar文件,而且你写的android代码的class文件的压缩包(可以解压看看里面实际的内容)。之后unity所需要使用的是res文件夹下的文件,classes.jar(android的)和AndroidManifest文件。


(ps:理论上来说现在版本的unity是直接可以使用android的aar包的,但是楼主在实际使用过程中一直会有问题,所以这边所使用的还是jar包和res文件的形式,如果有小伙伴使用aar成功的话请留言(本人是做Unity开发的,所以更不懂 - -))


4.创建Unity项目


打开unity,创建项目名称为UnityDemo,习惯性的Ctrl+S保存场景,名字随意。

右击Hierarchy面板,UI-Canvas新建一个画布Canvas,设置画布的Canvas Scaler的UIScale Mode为Scale With Screen Size,960*640.

往canvas中添加一个text和一个button,并调整他们的大小和位置,用于之后的事件操作和显示。

然后将我们之前导出的jar和res文件拷贝到Plugins/Android文件夹下



5. 编写unity脚本

新建一个AndroidControl的C#脚本,并将其挂载到Canvas对象上。(直接通过鼠标左键拖动到Canvas上)。打开脚本,在Start()方法中获取android的MainActivity对象。

private AndroidJavaObject jo;    void Start ()    {        //获取Android的Java接口        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); //获取java中UnityPlayer类        jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); //获取currentActivity对象}
首先获取unityPlayer实例,每个unity app在启动的时候都会有一个UnityPlayer实例。通过获取该实例里面currentActivity对象,其实就是我们的MainActivity实例。

我们可以在android studio中查看源码的方式查看UnityPlayer.class知道为什么是获取这个currentActivity:


创建方法ShowAndroidTime来获取系统时间并进行显示:

    //按钮点击时调用public void ShowAndroidTime()    {        //调用java函数getNowTime(),获得返回值string        string time = jo.Call<string>("getNowTime");        //调用java函数showToast,传入参数        jo.Call("showToast",new object[] { time});    }
首先调用MainActivity中的getNowTime方法得到时间,然后在调用showToast方法让时间Toast出来。

接下来是要对button设置点击事件去调用这个ShowAndroidTime方法。

Unity中选中button物体,然后在Inspector面板onclick点击+。由于我们的脚本是挂在到Canvas上的,所以需要选择canvas对面里面的AndroidControl脚本的ShowAndroidTime方法。


6. 导出Android app

将scene保存,然后点击file-->build settings,选择platform为android,然后点击switch platform,同时将要导出的scene add进来。

点击player settings进行一些android 导出的设置。在这里我们设置apk的名称为UnityWithAndroid,显示为横屏,设置包名为com.eam.unityandroid1,要注意的是把install location设置为Automatic,否则apk会安装失败,同时需要指定apk的签名。



注意:

没有签名新建签名:

勾选Create New Keystore-->点击Browse Keystore选择签名存放的地方-->设置签名密钥并确认(需谨记)-->Alias选择Create a new key-->

在弹出的面板中填好各种信息创建Key-->然后就可以使用刚建的keystore了-->打包。


最后点击build导出apk,如果已经连接上android设备的话,可以直接build and run进行导出和启动。

最终效果:



6.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); //安卓调用Unity方法            }        });    }
UnityPlayer.UnitySendMessage("Canvas","OnTimeResult",text);方法的意思是调用名称为Canvas对象上的OnTimeResult方法,传入的参数为text。这样我们的操作就完成了,重复上面的操作,我们来看下效果。


7.使用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查看)


The End!


原创粉丝点击