http://www.manew.com/thread-103445-1-1.html
Unity调用 接口实践与总结(包含Eclipse 和 AndroidStudio)
根据前人及大神的教程,这次博客分享下本人对Unity和Android交互的实践与总结,分享下亲身踩坑的经历。
首先,介绍下工具和环境
System
|
Windows 8.1 Pro(64bit)
|
Unity Version
|
Unity 5.6.0f3(64bit)
|
IDE
|
①Visual Studio Ultimate 2013
②Eclipse Mars.2 Release (4.5.2)
③Android Studio 2.3.1
|
JDK Version
|
1.8.0_121
|
SDK Version
|
25.2.3
|
测试机Android版本
|
4.4.2
|
目录:
一、AndroidStudio和Unity交互(导出ARR包)
二、Eclipse和Unity交互(导出JAR包)
三、AndroidStudio遇到的坑(错误解决方案)
四、Unity遇到的坑(错误解决方案)
一、先来聊聊AndroidStudio和Unity交互
1. 创建你的Unity 项目并设置player settings → settings for Android → Identification → PackageName(包名)和 Minimum API Level(最低支持的Android API版本)
<ignore_js_op>
2. 创建AndroidStudio Project
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
3. 添加依赖库并设置依赖关系
(1) 依赖库位置:
…Unity 5.6.0f3EditorDataPlaybackEnginesAndroidPlayerVariationsmonoReleaseClasses
<ignore_js_op>
(2) 将Classer.jar Cope到 libs 目录下。(本身是空的文件夹)
<ignore_js_op>
(3) 右键项目选择 Open Module Settings 或者直接按F4 打开 Project Structure窗口,并设置 Dependencies(依赖关系)。
<ignore_js_op> <ignore_js_op>
<ignore_js_op>
4. 编辑MainActivity.java
修改 MainActicity extends(继承)UnityPlayerActivity,然后编写功能
注释 setContentView(R.layout.activity_main);
[Java] 纯文本查看 复制代码
package com.nick.unitytest; import android.app.AlertDialog; import android.os.Bundle; import android.os.Vibrator; import android.widget.Toast; import com.unity3d.player.*; public class MainActivity extends UnityPlayerActivity { @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); //setContentView(R.layout.activity_main); } // 定义一个显示Dialog的方法,在Unity中调用此方法 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); } } |
5. 编辑AndroidManifest.xml
添加元数据 <meta-dataandroid:name="unityplayer.UnityActivity"android:value="true" />
添加用户权限<uses-permissionandroid:name="android.permission.VIBRATE" />
[XML] 纯文本查看 复制代码
<? xml version = "1.0" encoding = "utf-8" ?> < manifest xmlns:android = "http://schemas.android.com/apk/res/android" package = "com.nick.unitytest" > < application android:allowBackup = "true" android:icon = "@mipmap/ic_launcher" android:label = "@string/app_name" android:roundIcon = "@mipmap/ic_launcher_round" android:supportsRtl = "true" android:theme = "@style/AppTheme" > < activity android:name = ".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 > < uses-permission android:name = "android.permission.VIBRATE" /> </ manifest > |
6. 编辑activity_main.xml
删除xmlns:app=http://schemas.android.com/apk/res-auto
删除app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
[XML] 纯文本查看 复制代码
<? xml version = "1.0" encoding = "utf-8" ?> < android.support.constraint.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android" xmlns:tools = "http://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = "com.nick.unitytest.MainActivity" > < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Hello World!" /> </ android.support.constraint.ConstraintLayout > |
7. 编辑build.gradle
修改apply plugin: 'com.android.application' 为 applyplugin: 'com.android.library'
删除applicationId "com.nick.unitytest"
[Groovy] 纯文本查看 复制代码
apply plugin: 'com.android.library' [/align][align=left] android { compileSdkVersion 25 buildToolsVersion "25.0.3" defaultConfig { minSdkVersion 16 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile( 'proguard-android.txt' ), 'proguard-rules.pro' } } } dependencies { compile fileTree(include: [ '*.jar' ], dir: 'libs' ) androidTestCompile( 'com.android.support.test.espresso:espresso-core:2.2.2' , { exclude group: 'com.android.support' , module: 'support-annotations' }) compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha9' testCompile 'junit:junit:4.12' compile files( 'libs/classes.jar' ) } |
8. 导出并处理ARR
<ignore_js_op>
<ignore_js_op>
(1) Build 完之后 有个气泡弹出提醒,顺手点击Show in Explorer,错过了的话,可以在该工程的目录下找到
…UnityTestappuildoutputsaar
<ignore_js_op> (名字随意改啊)
(2) 打开ARR文件删除libs文件夹中的Classes.jar(这个是之前导入的依赖库,不删掉的话,在Unity项目中Build的时候会报“重复”的错)
<ignore_js_op> <ignore_js_op>
9. 导入Unity Project 中
(1) 在Assests 中新建Floder命名为“Plugins”,在“Plugins”文件夹中新建Floder命名为“Android”
<ignore_js_op>
(2) 将ARR文件放入“Android”文件夹中,并且从Android项目中复制一个AndroidManifest.xml一并放入文件夹中。
(3) 修改AndroidManifest.xml
这里一定要修改,不然Unity Build的时候会报错,具体是报找不到资源的错
参照Unity根目录下给出的AndroidManifest.xml作修改依据
位置:…Unity 5.6.0f3EditorDataPlaybackEnginesAndroidPlayerApk
<ignore_js_op>
引用android:theme="@style/UnityThemeSelector"
android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:debuggable="true"
作用:引用Unity的图标主题及应用标题
[XML] 纯文本查看 复制代码
<? xml version = "1.0" encoding = "utf-8" ?> < manifest xmlns:android = "http://schemas.android.com/apk/res/android" package = "com.nick.unitytest" > < application android:allowBackup = "true" android:supportsRtl = "true" android:theme = "@style/UnityThemeSelector" android:icon = "@drawable/app_icon" android:label = "@string/app_name" android:debuggable = "true" > < activity android:name = ".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 > < uses-permission android:name = "android.permission.VIBRATE" /> </ manifest > |
10. 创建场景,添加脚本,Build APK
塞几个按钮大家都懂,不细说。脚本搞定,把方法挂上按钮就好了。
<ignore_js_op>
脚本如下:
[C#] 纯文本查看 复制代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UnityTest : MonoBehaviour { public Text mText; public void BeCallFunc( string _content) { setMsg( ref _content); } private void setMsg( ref string _str) { mText.text = _str; } public void Btn_Dialog() { // Java Interface Of Android AndroidJavaClass jc = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>( "currentActivity" ); // Parameters string [] mObject = new string [2]; mObject[0] = "Jar4Android" ; mObject[1] = "Wow,Amazing!It's worked!" ; // Func string ret = jo.Call< string >( "ShowDialog" , mObject); setMsg( ref ret); } public void Btn_Toast() { AndroidJavaClass jc = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>( "currentActivity" ); jo.Call( "ShowToast" , "Showing on Toast" ); } public void Btn_Vibrate() { AndroidJavaClass jc = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>( "currentActivity" ); jo.Call( "SetVibrator" ); } public void Btn_CallBack() { AndroidJavaClass jc = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>( "currentActivity" ); jo.Call( "callUnityFunc" , "Canvas" , "BeCallFunc" , "Nick LAM" ); } } |
11. 要点总结
①添加元数据添加用户权限
②修改gradle脚本使导出的为library
③修改layout布局文件
④删除ARR包中libs的Classes.jar
⑤导入Unity时修改AndroidManifest的资源引用
二、聊聊Eclipse和Unity交互
1. 创建你的Unity Project 同上,注意Package Name 同 Minimum API Level
2. 創建Eclipse Android Project
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
3. 添加依赖库
两种方法:
(1) Add External JARs(添加外部JAR包)
<ignore_js_op>
(2) 创建“libs” 文件夹,并将依赖库cope文件夹下
<ignore_js_op>
4. 编辑MainActivity.java
同上啦!就不累赘
5. 编辑AndroidManifest.xml
添加元数据 <meta-dataandroid:name="unityplayer.UnityActivity"android:value="true" />
添加用户权限<uses-permissionandroid:name="android.permission.VIBRATE" />
[XML] 纯文本查看 复制代码
<? xml version = "1.0" encoding = "utf-8" ?> < manifest xmlns:android = "http://schemas.android.com/apk/res/android" package = "com.nick.unitytest" android:versionCode = "1" android:versionName = "1.0" > < uses-sdk android:minSdkVersion = "16" android:targetSdkVersion = "18" /> < application android:allowBackup = "true" android:icon = "@drawable/ic_launcher" android:label = "@string/app_name" android:theme = "@style/AppTheme" > < activity android:name = ".MainActivity" android:label = "@string/app_name" > < 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 > |
6. 导出并处理JAR
(1)导出操作:右键Project → Export → Java → JAR file
<ignore_js_op> <ignore_js_op>
(2)打开JAR文件删除libs文件夹中的Classes.jar(这个是之前导入的依赖库,不删掉的话,在Unity项目中Build的时候会报“重复”的错)
<ignore_js_op> <ignore_js_op>
7. 导入UnityProject
(1) 在Assests 中新建Floder命名为“Plugins”,在“Plugins”文件夹中新建Floder命名为“Android”
<ignore_js_op>
(2) 将ARR文件放入“Android”文件夹中,并且从Eclipse 的Android项目中复制一个AndroidManifest.xml一并放入文件夹中。
(3) 修改AndroidManifest.xml
这里一定要修改,不然Unity Build的时候会报错,具体是报找不到资源的错
参照Unity根目录下给出的AndroidManifest.xml作修改依据
位置:…Unity 5.6.0f3EditorDataPlaybackEnginesAndroidPlayerApk
引用android:theme="@style/UnityThemeSelector"
android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:debuggable="true"
作用:引用Unity的图标主题及应用标题
[XML] 纯文本查看 复制代码
<? xml version = "1.0" encoding = "utf-8" ?> < manifest xmlns:android = "http://schemas.android.com/apk/res/android" package = "com.nick.unitytest" android:versionCode = "1" android:versionName = "1.0" > < uses-sdk android:minSdkVersion = "16" android:targetSdkVersion = "18" /> < application android:allowBackup = "true" android:theme = "@style/UnityThemeSelector" android:icon = "@drawable/app_icon" android:label = "@string/app_name" android:debuggable = "true" > < activity android:name = ".MainActivity" android:label = "@string/app_name" > < 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 > < uses-permission android:name = "android.permission.VIBRATE" /> </ manifest > |
8. 创建场景,添加脚本,Build APK
同上啦!就不累赘了。
9. 要点总结
①添加元数据添加用户权限
②删除JAR包中libs的Classes.jar
③导入Unity时修改AndroidManifest的资源引用
三、AndroidStudio遇到的坑:
①问题:,升级完成后新建项目的时候遇无限Building“project name”gradle project info
原因:AS的每个版本会有对应的Gradle标配版本,所以它得把Gradle升级到标配版本
解决方法:下载Gradle离线包去手动更新(幸运的是,我正打算去下载离线包,它居然在祖国伟大的防火墙里经历了半个小时候后,顽强的帮我更新成功了)
②问题:SDKTools更新到最新的版本26.0.1,会报错
<ignore_js_op>
<ignore_js_op> (错误:无效的命令 android)
(另外还有个问题就是更新到最新的版本26.0.1,内置的SDK Manager.exe 就无法使用了)
原因:因为最新的SDK Tools 版本是不带命令行工具的,而Unity Build 安卓App要用到命令行工具
解决方案:1.如果你不慎更新了最新的版本,你可以到SDK官网单独下载带命令行的SDKTools(他给出带命令行工具的版本是25.2.3,内置SDK Manager 给出的更新提示可以升级到25.2.5,我没有去尝试,也不知道这个版本有没有带命令行工具,欢迎大家尝试后留言告诉我);2.如果你没有更新到最新的版本,请注意在打开Android Studio 的SDK Manager缺选SDK Tools
四、Unity 遇到的坑:
①问题:.2.2的版本当SDK Build-Tools≥24.x.x的时候会报错
原因:不支持呗
解决方案:把高版本的Hide起来,just like me
<ignore_js_op>