Unity和Android交互
前言: 在 Android 软件的开发中,会经常遇到 Unity 调用 Android 中的接口方法,不单是内购和广告的接入,普通的使用 Unity 去调用 Android 的原生消息框都会需要使用到交互相关的知识,接下来我们开始吧.
前期需要准备:
确认安装 Android Studio 开发软件.
整体步骤我分为:
-
基于 AS(Android Studio) 编写接口方法类并打出 jar
-
配置关联 Unity 编写调用 Android 原生方法接口方法
-
配置打包环境安装到 Android 设备
我的开发环境:
Unity 版本为 2017.4.6f1
Android Studio 版本为 3.2.0
1.基于 AS 编写接口方法类并打出 jar.
打开 Android Studio,选择 Start a new Android Studio project 新建一个 Android 工程.
下面是设置工程名字签名存放位置等等,这里我简单填写就好,目的是编写接口方法打出 jar,设置完毕后点击 Next.
这里我选择的是 Android 手机,最小兼容的版本为 API 16 ,也就是 Android 4.1,接着点 Next.
![](https://img.haomeiwen.com/i9013307/ad034b6b9e23eae6.png)
接着会提示让我们创建一个 Activity 类,这里我们选择 Add No Activity 不添加 Activity,再点击 Finish 完成创建.
![](https://img.haomeiwen.com/i9013307/46767750c0c60044.png)
工程创建完毕后,首先切换成 Project 视图,也就是绿框中的选项.
右键点击我们工程的主目录选择 New -> Module 创建一个新 Module.
![](https://img.haomeiwen.com/i9013307/cb721d4b05b8ba1b.png)
选择 Android Library 后点击 Next.
![](https://img.haomeiwen.com/i9013307/36bae746ef68ffe6.png)
设置好名字后点击 Finish .
![](https://img.haomeiwen.com/i9013307/41d24d8c58b226bb.png)
创建好 Module 后,别忘了添加用于编译的 Unity 库,将你 Unity 安装目录下的Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar
文件复制到我们工程中刚刚创建的 Module 的 libs 目录下.
![](https://img.haomeiwen.com/i9013307/d394e4f59b6aa50f.png)
回到 AS 界面,会发现我们创建的 Module 目录下的 libs 下出现了我们复制添加的 classes.jar 库.
![](https://img.haomeiwen.com/i9013307/c446825be37c037b.png)
光添加进来可没用,我们还需要给它添加依赖.
右键点击我们创建的 Module 选择 Open Module Settings 打开 Module 设置面板.
![](https://img.haomeiwen.com/i9013307/acd9c88624ff4d35.png)
点击我们创建的 Module 选择 Dependencies -> Jar dependency.
![](https://img.haomeiwen.com/i9013307/f4348c18b65aa0ab.png)
选择我们从 Unity 复制添加的 classese.jar 后点击 OK.
![](https://img.haomeiwen.com/i9013307/9d6941730096f3f7.png)
设置好依赖库后,我们可以开始编写接口方法类了,右键点击我们创建的 Module 目录下src/main/java/com.xxx.xxx
选择 New -> Java Class.
![](https://img.haomeiwen.com/i9013307/8266afc6e489e494.png)
设置好我们的 Activity 类名(就是我们的接口方法类)
![](https://img.haomeiwen.com/i9013307/17567da26aa2d0d5.png)
Superclass 是设置要继承的父类,这里我们事先设置为继承 UnityPlayerActivity.
在刚刚创建的 Java 文件中添加以下代码.
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
public class UnityAndroidActivity extends UnityPlayerActivity {
public void SetInfo() {
UnityPlayer.UnitySendMessage("Main Camera", "SetInfo", "Hello Unity!");
}
public void SendToast(String info) {
Toast.makeText(this, info, Toast.LENGTH_SHORT).show();
}
}
首先我定义了一个私有 String 类型的变量.接着还有两个方法.
方法一:调用 Unity 中名为 Main Camera 的游戏对象身上我们编写的脚本中的 SetInfo 方法,并发送一串字符为 SetInfo 的第一个参数.
方法二:将 info 的内容用 Toast 发送一条消息.
现在我们的方法接口类已经准备好了,可以开始将我们写好的类打包成 jar 库了.
首先点击上方的 Build 选择 Make Module 'xxx'.
![](https://img.haomeiwen.com/i9013307/4ae564dc85fc311e.png)
打开我们 Module 目录下的 build.gradle 文件.
![](https://img.haomeiwen.com/i9013307/9770583ff67c4cef.png)
在 build.gradle 中的最下方添加以下代码:
android.libraryVariants.all { variant ->
def task = project.tasks.create "jar${variant.buildType.name.capitalize()}",Jar
task.dependsOn variant.javaCompile
task.from variant.javaCompile.destinationDir
artifacts.add('archives',task)
}
task jarUnityLib(type: Jar, dependsOn: ['build']) {
archiveName = 'UnityAndroid.jar' //设置打出 jar 包的名字.
from('build/intermediates/javac/release/compileReleaseJavaWithJavac/classes')
destinationDir = file('build/libs')
exclude('com/Test/unityandroidlibrary/BuildConfig.class') //这里是自动设置好删除BuildConfig.class
exclude('com/Test/unityandroidlibrary/BuildConfig\$*.class')
exclude('**/R.class') //这里是自动设置好删除 R.class 文件
exclude('**/R\$*.class')
include('com/Test/unityandroidlibrary/UnityAndroidActivity*.class') //这里是选择要导出的方法接口类
}
注意: from 要根据自己的 Gradle 版本进行设置,由于我的 Gradle 版本是 4.6 ,是刚刚更新 AS 3.2.0 自动更新的.
如果是 4.6 之前的版本,大概要填 build/intermediates/javac/release
,具体所填,请自行查阅填之.
点击右上方的 Gradle 选择我们的 Module 的 Gradle 选择 other .
![](https://img.haomeiwen.com/i9013307/145de6af955d573a.png)
在 other 中找到我们编写的任务 jarUnityLib 并双击它.
![](https://img.haomeiwen.com/i9013307/c47cf579f827e021.png)
打包完毕后会出现以下 Log 消息.
![](https://img.haomeiwen.com/i9013307/bf9c2c5c46d38e95.png)
在我们的 Module 目录下会出现刚刚打出的 jar 包.
![](https://img.haomeiwen.com/i9013307/18ee1e4b669c3f68.png)
2.配置关联Unity,编写调用Android原生方法接口类
打开 Unity ,设置好工程名字后点击 Create project 创建工程.
![](https://img.haomeiwen.com/i9013307/66188187030b069c.png)
创建好工程后,右键点击 Assets 选择 Create -> Folder 创建文件夹.
![](https://img.haomeiwen.com/i9013307/fdbeb974564e3270.png)
按照下列格式创建文件夹,分别为 Plugins Android libs 三个文件夹.
![](https://img.haomeiwen.com/i9013307/800cb78304483855.png)
右键点击 Android 文件夹选择 Show in Explorer 打开目录.
![](https://img.haomeiwen.com/i9013307/6424fdc61b23cf6f.png)
在 Android 目录下创建一个 AndroidManifest.xml ,可以创建 Txt 文本后连同拓展名一起修改为 xml 文件.
![](https://img.haomeiwen.com/i9013307/4601124eba8d0b21.png)
添加以下代码:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:label="@string/app_name">
<activity android:name="com.Test.unityandroidlibrary.UnityAndroidActivity"
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screen
Layout|screenSize|smallestScreenSize|uiMode|touchscreen">
<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>
需要注意: 第三行所要设置的主 Activity 需要填写我们编写的方法接口类,由于是继承 UnityPlayerActivity 所以可以将主 Activity 设置为我们所编写的方法接口类.
右键点击我们打好的 UnityAndroid.jar 后选择 Show in Explorer .
![](https://img.haomeiwen.com/i9013307/850aea7d2cb90be6.png)
将打好的 jar 包复制一份到 Unity 中先前创建的 Plugins/Android/libs
目录下.
![](https://img.haomeiwen.com/i9013307/1dc5a908cd554a06.png)
回到Unity 界面,创建一个 Sctipts 文件夹用于放置 Unity 脚本,右键点击刚刚创建的文件夹选择
Create -> C# Script 创建脚本,脚本名字可以自定义设置.
![](https://img.haomeiwen.com/i9013307/65f4c0dbe0345402.png)
创建好脚本后打开它.
添加以下代码:
using UnityEngine;
public class UnityAndroidTest : MonoBehaviour
{
private AndroidJavaObject m_Jo;
private AndroidJavaClass m_Jc;
private string m_Info = null;
private void Start()
{
m_Jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
m_Jo = m_Jc.GetStatic<AndroidJavaObject>("currentActivity");
m_Jo.Call("SetInfo");
}
public void SetInfo(string info)
{
m_Info = info;
}
public void SendToast()
{
m_Jo.Call("SendToast", m_Info);
}
}
以上代码解析:
-
首先定义了 AndroidJavaObject 和 AndroidJavaClass 以及一个 String 类型的变量 m_Info .
-
Start 方法中初始化了 m_Jc 和 m_Jo .还调用Android 中我们编写 SetInfo 接口方法.
-
SetInfo 方法是用于给 Android 调用的公开方法,赋值当前类中的 m_Info .
-
SendToast 是辅助调用 Android 中发送当前类中 m_Info 内容到屏幕上.
编写并保存脚本后,回到 Unity 界面.
将我们编写好的脚本拖至 Main Camera 的 Inspector 中.
![](https://img.haomeiwen.com/i9013307/65c104b9b6f19502.png)
右键点击 Hierarchy 面板,选择 UI -> Button 创建一个按钮.
![](https://img.haomeiwen.com/i9013307/9249d1b98a1c6dbe.png)
点击我们刚刚创建的 Button ,将 MainCamera 拖至 Button 的 Inspector 面板的 OnClick 下.
点击 No Function 选择 UnityAndroidTest(也就是我们刚刚创建的脚本)-> SendToast()
![](https://img.haomeiwen.com/i9013307/9401446296844e61.png)
新建一个 Scenes 文件夹用于存放场景文件,使用快捷键 Ctrl + S
进行保存.
![](https://img.haomeiwen.com/i9013307/7d11a0a7d559cf31.png)
设置好场景名点击保存即可保存场景.
3.配置打包环境安装到Android设备
点击 File -> Build Settings 打开右边的界面.
确认当前是 Android 开发环境,点击 Android 再点击 Switch Platform 切换开发环境.
![](https://img.haomeiwen.com/i9013307/993a8f8007429385.png)
点击 Add Open Scenes 添加需要加载的场景.
Android 选项右方若有 Unity 的图标就代表现在是 Android 开发环境.
接着点击 Player Settings 进行打包前的基本设置.
![](https://img.haomeiwen.com/i9013307/2deb2d25776f2223.png)
配置解析:
设置应用的名字,设置好签名以及最低兼容的版本 Android 4.1 和默认最高的目标版本.
![](https://img.haomeiwen.com/i9013307/d28eb9d1f7540168.png)
准备完毕后,就可以用 USB 线连接你的 Android 手机.
确认连接完毕后点击 Build And Run 进行打包.
![](https://img.haomeiwen.com/i9013307/878cf6a90a1148a8.png)
打包成功后打开,点击 Button 按钮后会出现一条 Android 发送到 Unity 的一条 HelloUnity! 的消息.
这条消息是通过 Android 发送到 Unity , Unity 再通过调用 Android 发送消息的方法将收到的内容发送到屏幕上.
![](https://img.haomeiwen.com/i9013307/21f4a0b956eb0b7d.png)
到此 Unity 和 Android 的交互就完成了.比起 iOS 的交互, Android 的交互繁琐了许多.
第一次写技术文档,写的不好的地方请多多指教.