前言

使用Unity也有不短的时间了,安卓包也打过不少,但是对Unity与Android的交互却知之甚少。

因工作需求,需要在Android平台接一些sdk(扩展功能)。我就借此机会了解了下Unity与Android交互的一些知识,并做了一个简易实现。

现将实现步骤记录下来以供日后查阅。

一、开发准备

Unity、Android Stuido以及JDK安装,这些都是基本操作了,网上也有很多教程,这里不细述。

本次开发所使用的软件版本如下:

Android Studio 3.5

Unity 2018.3.10f1

Java 1.8.0191

 

二、要实现的功能

要在unity项目中进行安卓功能扩展,有两种方式:

1、Unity项目导出为Android工程,然后在Android Studio(以后简称为AS)中进行二次开发,添加扩展功能。这样的方式开发起来很灵活,改动起来也很方便,但是就是很麻烦,因为每次改动都要打一回安卓工程。

2、将扩展功能制作成Android库文件(jar包),然后将jar包导入到Unity中,直接使用。这样的方式,使用者无法修改这个库文件的功能,但也更便于使用 。

 

因为我将要做的功能可能会在团队内传播使用,也不需要每个人都去做改动。因此选择第二种方式。

所以本文的目的就是:

制作一个Android库文件(jar包),然后在Unity中使用它。

三、如何制作Android库文件

1、新建Android工程

 打开AS,新建一个Android工程,选择Empty Activity,配置工程名称、包名、位置以及语言,如下图

【Unity与Android】01-Unity与Android交互通信的简易实现_第1张图片

 语言最好选Java,因为Java和C#的语法极为相似,学习成本很低。

 

工程创建之后,默认显示的是Android视图下app的工程结构,如下图。能看到在包名下有一个MainActivity.java的文件,这是安卓app的入口,不过这里并不打算使用它,忽略即可。

【Unity与Android】01-Unity与Android交互通信的简易实现_第2张图片

 

2、创建一个Android Library 模块

 选中app,然后右键,选Module,在Create New Module窗口中选择 Android Library 

【Unity与Android】01-Unity与Android交互通信的简易实现_第3张图片

 

 填入Library name、Module name 、Package name以及Language后,点完成。

 这里的Package name好像是可以改的,不必和之前创建工程时完全一样(未验证)。不过为了少点事,还是先保持一致吧。

【Unity与Android】01-Unity与Android交互通信的简易实现_第4张图片

 

 现在可以看到,在工程中同时存在着app和mysdk模块,它俩是平级存在的,并且都有自己的源码目录(com.letui.mysdk),以及清单目录(manifests)。

【Unity与Android】01-Unity与Android交互通信的简易实现_第5张图片

 app部分可以不用管了,后续只对mysdk模块进行操作。

 

 3、引入Unity对接Android的库文件 

  1)在unity的安装目录下件,找到一个名为classes.jar的文件

  我的目录为 D:\Unity2018\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Classes

  2)然后将classes.jar粘贴到mysdk模块的libs目录下(需要将工程切换到project视图)

  额外说明:

  在il2cpp目录下也有一个名称一样的classes.jar文件,其目录为

   D:\Unity2018\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Classes

  这两个文件的选择,与unity的Player Setting中脚本后端设置有关。如下图

  【Unity与Android】01-Unity与Android交互通信的简易实现_第6张图片

    脚本后端用哪个就,就选哪个目录下的classes.jar

  3)选中刚粘贴的classes.jar文件,右键,选择 Add as Library,出现一个弹窗口,默认选中mysdk模块,直接点确定

【Unity与Android】01-Unity与Android交互通信的简易实现_第7张图片

  然后,这个classes.jar文件就被引入到工程中了,展开三角,可以看到如下三个模块,其中就有com.unity3d.player。如下

  【Unity与Android】01-Unity与Android交互通信的简易实现_第8张图片

 4、创建本模块的Activity文件

  1)展开mysdk模块下的src目录,选中com.leitui.mysdk,然后右键,新建一个Activity,选择Empty Activity,输入Activity Name以及Package Name和Language,勾掉Generate Layout File, 完成。

【Unity与Android】01-Unity与Android交互通信的简易实现_第9张图片

 

 新建的SDKMainAcivity.java脚本,默认继承自AppCompatActivity,并带有一个onCreate方法,如下:

【Unity与Android】01-Unity与Android交互通信的简易实现_第10张图片

 

现将SDKMainActivity脚本内容修改为继续自UnityPlayerActivity ,并添加两个方法 UnityCallAndroid 和 AndroidCallUnity

UnityCallAndroid 用来接受Unity的调用,AndroidCallUnity用于向unity发起调用。具体代码如下:

 1 package com.letui.mysdk; 2  3 import androidx.appcompat.app.AppCompatActivity; 4  5 import android.os.Bundle; 6 import android.widget.Toast; 7  8 import com.unity3d.player.UnityPlayer; 9 import com.unity3d.player.UnityPlayerActivity;10 11 public class SDKMainActivity extends UnityPlayerActivity {12 13     @Override14     protected void onCreate(Bundle savedInstanceState) {15         super.onCreate(savedInstanceState);16     }17 18     //unity调用Android19     public void UnityCallAndroid () {20 21         Toast.makeText(this,"unity调用android成功", Toast.LENGTH_LONG).show();22 23         AndroidCallUnity();24     }25 26     //android调用unity27     public void AndroidCallUnity () {28 29         //第1个参数为Unity场景中用于接收android消息的对象名称30         //第2个参数为对象上的脚本的一个成员方法名称(脚本名称不限制)31         //第3个参数为unity方法的参数32         UnityPlayer.UnitySendMessage("receiveObj", "UnityMethod", "This is args.");33     }34 }

 

5、将模块打包

  打包方法有两种。

  一是手动进行构建,然后在Build/intermediates/packaged-classes/release目录下找到相应的jar包(这个jar包默认名称为classes.jar,为了区分,需要自己改名称);

  二是用gradle命令。

  打开本模块的build.gradle文件,在文件尾添加如下的一组命令。

//----------------这是一组将module导出为jar的gradle命令-------------------// mysdk为自定义的jar包名称//task to delete the old jartask deleteOldJar(type: Delete) {    delete 'release/mysdk.jar'}//task to export contents as jartask exportJar(type: Copy) {    from('build/intermediates/packaged-classes/release/')    into('release/')    include('classes.jar')    ///Rename the jar    rename('classes.jar', 'mysdk.jar')}exportJar.dependsOn(deleteOldJar, build)//---------------------------命令结束------------------------------

【Unity与Android】01-Unity与Android交互通信的简易实现_第11张图片

 这组命令的功能就是打包方法1的自动化版。

 build.gradle文件修改后,会提示要求同步,直接同步即可。同步结束,在IDE右上点开Gradle窗口,在other下找到exportJar命令。

【Unity与Android】01-Unity与Android交互通信的简易实现_第12张图片

 双击exportJar命令,等一会就会自动生成本模块的jar文件了。

生成的文件位于mysdk/release/目录下,如下图

 【Unity与Android】01-Unity与Android交互通信的简易实现_第13张图片

6、修改AndroidManifest.xml文件
  1)打开本模块的AndroidManifest.xml文件,文件位于mysdk/src/main目录下,如下图:

【Unity与Android】01-Unity与Android交互通信的简易实现_第14张图片

  这个文件的内容,目前只有一对application标签和activity标签 

【Unity与Android】01-Unity与Android交互通信的简易实现_第15张图片

  删掉这三行,将其内容修改为如下: 

 1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3     package="com.letui.mysdk"> 4  5      6     <application android:label="MySDK"> 7  8          9         <activity android:name="com.letui.mysdk.SDKMainActivity">10             <intent-filter>11                 <action android:name="android.intent.action.MAIN" />12                 <category android:name="android.intent.category.LAUNCHER" />13             intent-filter>14 15             16             <meta-data android:name="unityplayer.UnityActivity" android:value="true" />17         activity>18     application>19 20 manifest>

这其中有三个要注意的点,注释中都有说明。修改完成后保存。

至此,在AS中的操作就结束了。

 

四、在unity中使用jar文件

1、新建一个Unity工程。

  a.新建一个Unity工程,在Assets目录下新建Plugins/Android/bin目录。

  b.将第三步修改的AndroidManifest.xml文件拷贝到Assets/Plugins/Android目录下

  c.将第三步生成的mysdk.jar文件拷贝到Assets/Plugins/Android/bin目录下

  完成之后文件结构图如下:

    【Unity与Android】01-Unity与Android交互通信的简易实现_第16张图片

  libs目录用于存放其它android插件的jar文件,没有也可以不用创建。

 

 2、制作一个UI界面

 a.在SampleScene场景中创建一个Canvas,并创建一个名为"receiveObj"的对象,在receiveObj之下再放一个按钮和一个Text。

 按钮用于触发调用Android方法。

 Text用于显示Android调用Unity方法传递来的参数。如下图:

【Unity与Android】01-Unity与Android交互通信的简易实现_第17张图片

 这里要注意,receiveObj的名称必须与SDKMainActivity类的AndroidCallUnity方法中的UnityPlayer.UnitySendMessage方法的第一个参数保持一致。

【Unity与Android】01-Unity与Android交互通信的简易实现_第18张图片

  

 b.创建一个SDKTest.cs文件,将脚本挂在receiveObj对象上。如下: 

【Unity与Android】01-Unity与Android交互通信的简易实现_第19张图片

 

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

 其中必须要有UnityMethod方法,因为它在AndroidCallUnity方法中的UnityPlayer.UnitySendMessage的第二个参数已经指定了。如果不存在的话,调用就会出错。

  jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");  jo = jc.GetStatic("currentActivity");

这两句,一个是获取到UnityPlayer类,一个是获取到类的实例。
到于为什么这样能取到我创建的模块的SDKMainActivity的实例,还有待探究。反正目前这么写了就行了。

 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通信成功

  演示见下图:

调用 前:【Unity与Android】01-Unity与Android交互通信的简易实现_第20张图片,调用后: 【Unity与Android】01-Unity与Android交互通信的简易实现_第21张图片

 

五、一点说明

1、模块的包名和Unity的Bundle Identifier可以不一致(至少在Module模式下,是可以不一致的)。

说明:写这条是因为其它相关文章全都要求两边保持一致,而如果模块的包名要跟着Unity工程走,也太蛋疼了,所以验证了下。

2、将AndroidManifest.xml引入到Unity之后,在unity中设置的Product Name就无效了。

需要在AndroidManifest.xml的application标签中,添加android:label属性来指定。

  

      初次接触Android开发,以上内容如有错误,还请不吝指出。

 

  本文件所使用的Android工程和Unity工程源码在此:安卓工程  Unity工程

转载于:https://www.cnblogs.com/imteach/p/11567481.html

更多相关文章

  1. android展讯平台重要的打包命令及生成镜像文件的Linux命令
  2. 最全的android图片加密
  3. 关于Air端与android端的通信实现
  4. android跨进程IPC通信探讨(A应用与B应用通信)
  5. Android开发之网络请求通信专题(二):基于HttpClient的文件上传下载
  6. Android学习札记44:解读APK反编译后得到的布局文件
  7. Android中Gif图片的显示
  8. Android IPC进程间通信,Binder机制原理及AIDL实例
  9. android文件系统及其制作

随机推荐

  1. 如何在android中实现swipe的手势功能及页
  2. [Android算法] Android蓝牙开发浅谈
  3. Android(安卓)Activity生命周期图解
  4. 非常详细的测试unity与android之间的通讯
  5. Android应用内切换语言
  6. android 电话状态的监听
  7. Android(安卓)实现闪屏页和右上角的倒计
  8. Android笔试总结
  9. Android的Activity屏幕切换动画(二)-左右
  10. android开源项目二、