赞
踩
转自 Unity与Android交互之✨| 使用AndroidJavaProxy代理方式,让Android与Unity通讯
以前也接入过原生端,没有这么深入。以前unity嵌入到原生端app中,都是打包成原生工程,调用外部是通过callstatic方法调用原生端静态方法,原生端调用内部通过简单的sendmessage。
所以转载一些文章,顺便记录自己的理解,下次遇到好快速想起。根据unity的性格, 这些原生端SDK整合方式过个十年都不一定有什么变化。所以记录是有价值的。
unity手册本身写了unity整合安卓sdk的方式以及两者的交互 : 构建和使用适用于 Android 的插件
Unity与Android进行交互
一直都是Unity开发Android的一个常用手段UnitySendMessage
和AndroidJavaProxy
AndroidJavaProxy代理方式
进行交互调用可以知道Unity调用Android逻辑,Android逻辑以Plugins的概念被Unity执行;
Plugins存在方式主要有两种:
1)so库,使用Android JNI API方式提供接口,与其他平台基本一样,是比较通用的方式;
2)jar库/aar库,使用JAVA API方式提供接口,Android平台特有的方式,是该分享关注的部分;
描述jar库/aar库方式时,假设开发语言均为Java,不是Kolin;
在一些情况下,安卓SDK中会有so包和aar包共存的,也有只存在aar的。
共存
单独
上面两个图都能正常运行,后面的图是我更换了安卓的SDK后的模样。
下面我们就先从Android Studio
端开始一步一步做起,Android Studio
下面统称AS
打开AS 之后新建一个项目,如下图几个步骤很简单
然后就是等它把工程新建完打开工程后
File->New->New Module
,选中Android Library
,新建一个Module。
我这里新建的Module
名字是MyunityLibrary
。
在这里创建一个AndroidLibrary
,起名为MainActivity
,创建好后是这个样子
简单修改了名字和路径之后,我们就进入这个AS工程了
1
现在这里有两个AndroidManifest
,一个是本工程的,还有一个就是新建的unityLibrary
的。
这里把app的AndroidManifest
中背景的部分全部复制到我们新建的那个Library的AndroidManifest
中。
然后记得把我们创建的Library的 package
改为com.example.myunitylibrary
,然后报红的全删掉.
并且加上下面这一段代码,这段代码必须加上才能与Unity交互!
<meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
改好了如下所示
1
这个时候还报红是因为我们的Library中没有这个类,给他创建一个即可
这个时候AndroidManifest
就算暂时的改好了!
Unity的classes.jar
文件,这个目录在安装Unity的路径下
我的路径是在
D:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
下。
复制,粘贴到AS的 libs目录下,如下所示
选中class.jar->右键->AddAsLibrary->选中unitylibrary->Ok
。
在我们的Library下新建一个接口
然后简单写几个方法用于测试交互,如下所示:
在我们的MainActivity中写代码,示例如下:
1
写了一个Unity调用Android的入口函数setCallback,然后再通过Unity传过来的值调用AS端的接口给Unity发送数据
具体Unity端怎样操作的还需要往下看!
选中Library然后 Build -> Make Module ‘ ’
等待编译
然后AS会多出来一个build文件夹,我们找到outputs -> aar 下的aar包,这个就是我们需要在Unity中导入的文件,保存好就行
1
然后打开这个aar包,把lib文件夹下的class包给删掉,如下所示
如果不能直接打开,把aar修改为zip格式,删掉class后再改回aar格式即可!
然后AS端的操作就算完成了,接下来Unity中的就简单了,一起来看一下!
首先我们打开Unity新建一个项目
然后新建一个Plugins文件夹,把我们的aar包放进去,如下所示:
然后新建一个场景写一个脚本UnityAndroidDemo
代码内容如下:
- using UnityEngine;
- using UnityEngine.UI;
-
- public class setAndroidTest : MonoBehaviour
- {
- public Text Stringtext;
- public Text Inttext;
- public Button button;
-
- public static setAndroidTest instance;
- void Start()
- {
- instance = this;
- //创建安卓端入口
- AndroidJavaObject jo = new AndroidJavaObject("com.example.myunitylibrary.MainActivity");
- setAndrodCallback _setAndrodCallback = new setAndrodCallback();
-
- button.onClick.AddListener(()=>
- {
- // 设置回调函数接口,Unity端向安卓端发消息
- jo.Call("setCallback", _setAndrodCallback);
- });
- }
-
- public class setAndrodCallback : AndroidJavaProxy
- {
- public setAndrodCallback() : base("com.example.myunitylibrary.UnityCallBackTest") { }
- public void IntCallBack(int content) { setAndroidTest.instance.Stringtext.text = content.ToString(); }
- public void StringCallback(string msg) { setAndroidTest.instance.Inttext.text= msg; }
- }
- }
这里添加下自己的理解,
1. 继承自AndroidJavaProxy实际上是一个安卓工程中的功能类 这个类不继承自Activity 不是activity类
2. 在
public IijkPlayerNativeAndroid2(string url) : base("com.mg.cc.ijkvideo.utils.MediaPlayerWrapper")
中,IijkPlayerNativeAndroid2是安卓SDK工程中com.mg.cc.ijkvideo.utils这个package(安卓中的包)里面的MediaPlayerWrapper类的Unity代表。
3. 当安卓工程中有一些Activity类的方法传入了IijkPlayerNativeAndroid2参数的时候,unity中的代码可以实现相同的操作,例如安卓代码中的位于com.example.myunitylibrary的package的activityA这样调用了,则unity可以这样写。
activityA.someCall(IijkPlayerNativeAndroid2类的对象)
- AndroidJavaObject jo = new AndroidJavaObject("com.example.myunitylibrary.activityA");
- IijkPlayerNativeAndroid2 i= new IijkPlayerNativeAndroid2(url);
- jo.Call("someCall", i);
4. 继承自AndroidJavaObject的类是安卓工程中的继承自Activity类。构造函数也是要指明包名加类名
-
- private AndroidJavaObject _self;
-
- private const string ClassName = "com.mg.cc.ijkvideo.utils.MediaPlayerWrapper";
-
- _self = new AndroidJavaObject(ClassName);
5. Call方法是由继承自AndroidJavaObject的类发起, 尖括号里面的是返回值类型,第一个参数是安卓工程的函数名字,后面的是该函数的参数
var id = (IntPtr) _self.Call<int>("getUnityExternalTexture");
6. 这里是安卓SDK往Unity端传送直播画面,两个端之间传输数据只能够用基本数据类型,例如string,char,int,float等,而不能用端的专有类类型。因为一个端不能识别另个端的类类型里面的内容。所以传输直播画面,方法是用整数指针。如下
- public Texture2D UnityExternalTexture
- {
- get
- {
- if (_texture) return _texture;
-
- var id = (IntPtr) _self.Call<int>("getUnityExternalTexture");
- if (id != IntPtr.Zero)
- {
- _texture = Texture2D.CreateExternalTexture(1920, 1080, TextureFormat.RGB565, false, true, id);
- }
-
- return _texture;
- }
- }
- public void UpdateExternalTexture()
- {
- int id = _self.Call<int>("updateTexture");
- _texture.UpdateExternalTexture((IntPtr) id);
- }
脚本中写了一个setAndrodCallback 类,在这个类中有一个跟安卓端中的接口一模一眼
其中下面这行代码中的字符串一定要跟我们AS端的包名+类名一致
public setAndrodCallback() : base("com.example.myunitylibrary.UnityCallBackTest") { }
然后调用AS端的入口函数setCallback
启动交互
再把从安卓端传过来的值赋给Unity中的Text文本即可
最后就是打包成APK进行测试啦
File -> Build Setting -> Playrt Setting
然后点击Build进行打包即可
测试结果如下:
点击Button按钮之后,Android端的值就传给Unity并显示到UI上面了!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。