Unity2019.3.3与Android Studio 3.6.1 交互通信
最近做了一项目需要用到Unity和原生安卓之间的通讯,用的是Unity2019.3.3版本的Android Studio 3.6.1版本的导出jar 在网上看了许多帖子发先都是过时了,今天趟了一天坑,不过总有搞定了
一.参考资料
https://www.cnblogs.com/imteach/p/11567481.html
https://blog.csdn.net/qq_33337811/article/details/88556927
https://blog.csdn.net/xiayiye5/article/details/79639044https://www.jianshu.com/p/16b33d3aedcd
https://www.jianshu.com/p/8256c0da444a
https://docs.unity3d.com/Manual/AndroidUnityPlayerActivity.html(没事多看看官网文档还是好的)
二.实际操作
本次开发所使用的软件版本如下:
Android Studio 3.6.1
Unity 2019.3.3f1
1.制作jar文件
1.1新建Android Studio(以下简AS) 工程
打开AS之前有工程的话点击File - New - New Project
显示选择界面 点击Empty Activity - Next
填写项目名称Unity2Android (这个名可以随便填后面用不到),Minimum SDK 最好和Unity的项目选择一样的
做到这一步你就建成一个新的AS项目了,不过然并卵
1.2添加Modules
之前看到许多帖子在project属性栏中直接添加,我发现这样做会出现嵌套问题,所有自己有摸索了一种新的添加方式
点击 File - Project Structure
点击Modules - +
选中Android Library 点击 Next
这里的参数比较重要,这个就是我们导出jar用的Modules,注意这个Module Name和Package Name 这里后面会用到,Minimum SDK 最好和Unity的项目选择一样的
填好name后,点击Finish 你就拥有一个可以导出的Jar的Module了
添加Compile SDK Version和Build Tools Version的版本就可以点击Apple 和OK
然后 AS项目会加载一会
在你的AS项目中就可以看到有一个新的u2a的文件夹这个就是刚才添加的Modules
1.3添加Unity classes.jar到AS项目中
点击三角号到选中Project - 点击文件u2a - libs - 在libs上点击右键 - 打开Show in Explorer
将 classes.jar 到 u2a\libs中
classes.jar路径:Unity(Unity的安装路径下)\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Classes
据我所知classes.jar在Unity2019.2以下的版本中有UnityPlayerActivity类,在Unity2019.2以上的版本中将UnityPlayerActivity取消了不过可以在Unity(Unity的安装路径下)\Editor\Data\PlaybackEngines\AndroidPlayer\Source\com\unity3d\player中找到
在拷贝的classes.jar上点击右键选中Add as Library,添加到u2a moduls中
1.4添加Unity和安卓的通信类和添加UnityPlayerActivity.java
将Unity(Unity的安装路径下)\Editor\Data\PlaybackEngines\AndroidPlayer\Source\com\unity3d\player中的UnityPlayerActivity.java拷贝到u2a\main\java\com.xiaoma.u2a(这里你是自己的包名)中
在u2a\main\java\com.xiaoma.u2a中新建一个Empty Activity,
此时你的文件结构应该如下图
将UnityPlayerActivity.java的引入更新
//package com.unity3d.player.;
// 添加
package com.xiaoma.u2a;
import com.unity3d.player.IUnityPlayerLifecycleEvents;
import com.unity3d.player.UnityPlayer;
编写MainActivity.java
package com.xiaoma.u2a;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
public class MainActivity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
//unity调用Android
public void UnityCallAndroid () {
Toast.makeText(this,"unity调用android成功", Toast.LENGTH_LONG).show();
AndroidCallUnity();
}
//android调用unity
public void AndroidCallUnity () {
//第1个参数为Unity场景中用于接收android消息的对象名称
//第2个参数为对象上的脚本的一个成员方法名称(脚本名称不限制)
//第3个参数为unity方法的参数
UnityPlayer.UnitySendMessage("receiveObj", "UnityMethod", "This is args.");
}
}
修改u2a中的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xiaoma.u2a">
<application>
<!-- 这个android:name的值必须为包名+类名-->
<activity android:name="com.xiaoma.u2a.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>
1.5添加build.gradle文件
注意这个build.gradle是u2a moduls的build.gradle文件不是项目的build.gradle
u2a moduls的build.gradle位置在u2a\build.gradle
在build.gradle文件尾部添加
//----------------这是一组将module导出为jar的gradle命令-------------------
task deleteOldJar(type: Delete) {
delete 'release/AndroidPlugin.jar'
}
//task to export contents as jar
task exportJar(type: Copy) {
from('build/intermediates/aar_main_jar/release/')
into('release/')
include('classes.jar')
///Rename the jar
rename('classes.jar', 'AndroidPlugin.jar')
}
exportJar.dependsOn(deleteOldJar, build)
//------------命令结束------------------------------
其中在这里插入代码片from('build/intermediates/aar_main_jar/release/')
的路径和AS版本有关每个不同的AS版本的不同
刷新Gradle
点击u2a - other - exportJar 会在u2a\release中生成AndroidPlugin.jar
就是我们刚才在配置的u2a modules 然后将AndroidPlugin.jar复制到unity项目中Assets\Plugins\Android中
2.Unity工程
参考:https://www.cnblogs.com/imteach/p/11567481.html
2.1、新建一个Unity工程。
a.新建一个Unity工程,在Assets目录下新建Plugins/Android/bin目录。
b.将第三步修改的AndroidManifest.xml文件拷贝到Assets/Plugins/Android目录下
c.将第三步生成的mysdk.jar文件拷贝到Assets/Plugins/Android/bin目录下
完成之后文件结构图如下:
libs目录用于存放其它android插件的jar文件,没有也可以不用创建。
2.2、制作一个UI界面
a.在SampleScene场景中创建一个Canvas,并创建一个名为"receiveObj"的对象,在receiveObj之下再放一个按钮和一个Text。
按钮用于触发调用Android方法。
Text用于显示Android调用Unity方法传递来的参数。如下图:
这里要注意,receiveObj的名称必须与SDKMainActivity类的AndroidCallUnity方法中的UnityPlayer.UnitySendMessage方法的第一个参数保持一致。
b.创建一个SDKTest.cs文件,将脚本挂在receiveObj对象上。如下:
SDKTest脚本的内容如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SDKTest : MonoBehaviour
{
private AndroidJavaClass jc;
private AndroidJavaObject jo;
private Button btn;
private Text text;
private void Awake()
{
btn = transform.Find("Button").GetComponent<Button>();
text = transform.Find("Text").GetComponent<Text>();
//这两行是固定写法
jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
btn.onClick.AddListener(OnBtnClickHandler);
}
private void OnBtnClickHandler ()
{
//调用Android中的方法UnityCallAndroid
jo.Call("UnityCallAndroid");
}
/// <summary>
/// 被Android中AndroidCallUnity调用
/// </summary>
/// <param name="str"></param>
public void UnityMethod(string str)
{
Debug.Log("UnityMethod被调用,参数:" + str);
text.text = str;
}
}
其中必须要有UnityMethod方法,因为它在AndroidCallUnity方法中的UnityPlayer.UnitySendMessage的第二个参数已经指定了。如果不存在的话,调用就会出错。
jc = new AndroidJavaClass(“com.unity3d.player.UnityPlayer”);
jo = jc.GetStatic(“currentActivity”);
这两句,一个是获取到UnityPlayer类,一个是获取到类的实例。
到于为什么这样能取到我创建的模块的SDKMainActivity的实例,还有待探究。反正目前这么写了就行了。
2.3、打包并测试。
在unity中设置Bundle Identifier和Company等信息之后,打一个apk包。
安装后运行,能正常显示UI。
点击按钮后,显示了一个Toast,提示“Unity调用Android成功”,说明jar包中的UnityCallAndroid方法被调用。
Unity->Android通信成功。
同时屏幕上方的NewText被变更为“This is args”,"This is args"是 AndroidCallUnity方法中传递给UnityMethod方法的参数。
这表示Android->Unity通信成功。
演示见下图:
调用 前:在这里插入图片描述,调用后:
3总结
1.注意classes.jar的版本
2.注意AS的版本和from(‘build/intermediates/aar_main_jar/release/’) `的路径
3.主要AndroidManifest的配置
推荐阅读
-
详解Android activity与fragment之间的通信交互
-
Unity与Android Studio交互的实现
-
Android Studio 与 Unity3d交互。归纳版。
-
Android studio 与Unity交互
-
Unity与Android Studio交互
-
Unity与Android Studio交互的实现
-
unity-与Android交互(unity5、android studio)
-
Android Studio 与 Unity 的交互——加载 Unity 导出的工程到 Android Studio 中
-
Unity 与Android的交互(Android studio)
-
unity-与Android交互(unity5、android studio)