引言

最近为了实现Unity与Android之间的通信,在网络上发现了很多种实现方案。有打包Jar的,有打包aar的,有直接拷贝文件的。试了几种方案虽然都能解决需求,但是使用起来给我的感觉并不是很舒服。在各种尝试中,已了解了Unity和Android之间通信的底层原理。该方案为本人结合Java特性所给出,可以减少很多其它方案的一些不明确以及繁琐的步骤。

本文适用对象

  • 有一定的Unity开发经验,会使用Unity
  • 有一定的Android开发经验,会使用AndroidStudio

方案优势

  • 不需要引用unity下的class.jar
  • 不用在Unity的/Plugins/Android下放置AndroidManifest.xml文件
  • Unity打包时PackageName不依赖于引用文件
  • 发布简单,只需要导出arr并直接拷贝到/Plugins/Android目录下即可使用,不用对文件做任何修改

文章DEMO对应的IDE版本

  • AndroidStudio 3.0 (2.1亲测通过)
  • Unity 2017.2 (5.4.3亲测通过)

流程

Android部分

创建AndroidStudio项目

  1. 首先我们打开AndroidStudio,并创建一个新项目,这里随便填写项目名、包名即可,因为这个项目我们后面并不会用到。
  2. SDK我们选最低的就行。
  3. Activity我们选个EmptyActivity也行。

     

    1.png

     

    然后我们点击「Finish」完成AndroidStudio项目创建。

创建和unity交互的Moudle项目

  1. 项目创建好以后开始我们的主菜,选中app然后新建一个moudle

     

    2.png

  2. 类型选择「Android Library」

     

    3.png

  3. Application/Library name认真填写,之后为arr导出的名称,这里我们叫「MyUnityLib」。

  4. Module name没有强迫症就不用管它

  5. Package name认真填写,之后unity里会用到,不过它和unity导出的包名没有什么关系这里我们叫「com.jing.unity」好了

  6. Minimum SDK能选多低选多低,反正不超过unity发布的版本就行

     

    4.png

  7. 创建

  8. 然后我们在com.jing.unity包下创建一个类,作为Unity和Android通信的核心类,名字尽量炫酷一点,这里我们叫「Unity2Android」

     

    6.png

编写Android端代码

  1. 然后我们直接粘贴该类的代码,讲解直接看注释。这里我们通过Java的反射原理来获取本来导入class.jar类才能引用到的com.unity3d.player.UnityPlayer包下的currentActivity上下文。同理给unity发消息也是反射原理。「getActivity」和「callUnity」这两个方法,有一定的开发经验应该很容易理解。
    这里我们实现一个简单的接口「showToast」。

         package com.jing.unity;          import android.app.Activity;     import android.widget.Toast;          import java.lang.reflect.InvocationTargetException;     import java.lang.reflect.Method;          /**      * Created by Jing on 2018-1-18.      */     public class Unity2Android {              /**          * unity项目启动时的的上下文          */         private Activity _unityActivity;         /**          * 获取unity项目的上下文          * @return          */         Activity getActivity(){             if(null == _unityActivity) {                 try {                     Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");                     Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);                     _unityActivity = activity;                 } catch (ClassNotFoundException e) {                      } catch (IllegalAccessException e) {                      } catch (NoSuchFieldException e) {                      }             }             return _unityActivity;         }              /**          * 调用Unity的方法          * @param gameObjectName    调用的GameObject的名称          * @param functionName      方法名          * @param args              参数          * @return                  调用是否成功          */         boolean callUnity(String gameObjectName, String functionName, String args){             try {                 Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");                 Method method =classtype.getMethod("UnitySendMessage", String.class,String.class,String.class);                 method.invoke(classtype,gameObjectName,functionName,args);                 return true;             } catch (ClassNotFoundException e) {                  } catch (NoSuchMethodException e) {                  } catch (IllegalAccessException e) {                  } catch (InvocationTargetException e) {                  }             return false;         }              /**          * Toast显示unity发送过来的内容          * @param content           消息的内容          * @return                  调用是否成功          */         public boolean showToast(String content){             Toast.makeText(getActivity(),content,Toast.LENGTH_SHORT).show();             //这里是主动调用Unity中的方法,该方法之后unity部分会讲到             callUnity("Main Camera","FromAndroid", "hello unity i'm android");             return true;         }     }

导出arr准备给unity使用

  1. 代码写好了我们选中module然后选择「Build」「Rebuild Project」

     

    7.png

  2. 接着将这个arr文件找到,就是我们要导入到unity的文件了。

Unity部分

  1. 创建一个unity项目

  2. 创建目录Assets/Plugins/Android,并将刚才导出的arr文件放到该文件夹下,我们的导入就算完成了。没错就是这么Easy,然后我们看看怎么来调用它。

     

    8.png

  3. 在界面上放一个按钮,并且创建一个Script绑定到「Main Camera」。用一个文本控件来展示Android发送过来的消息。

  4. Script的代码内容如下

    using UnityEngine;using UnityEngine.UI;public class Main : MonoBehaviour {    ///     /// 场景上的文本框用来显示android发送过来的内容    ///     public Text text;    ///     /// android原生代码对象    ///     AndroidJavaObject _ajc;    void Start () {        //通过该API来实例化导入的arr中对应的类        _ajc = new AndroidJavaObject("com.jing.unity.Unity2Android");    }        void Update () {            }    ///     /// 场景上按点击时触发该方法    ///     public void OnBtnClick()    {        //通过API来调用原生代码的方法        bool success = _ajc.Call("showToast","this is unity");        if(true == success)        {            //请求成功        }    }    ///     /// 原生层通过该方法传回信息    ///     ///     public void FromAndroid(string content)    {        text.text = content;    }}
  5. 然后打包APK到我们的Android设备上进行测试。

     

    9.png

  6. 点击按钮,查看效果

     

    10.png

DEMO地址

  • 「国外git」GitHub:https://github.com/power-pieces/unity_with_android
  • 「国内git」Coding:https://coding.net/u/jinglikeblue/p/unity_with_android/git

结束语

  • aar和jar的区别各位可以自行百度了解。
  • 如果要对接第三方库,可以在moudle下对接,并打包aar给Unity使用。切记jar需要放到aar的libs下引用,才可以在打包的时候一并导出。通过gradle的网络下载编译方式是不会被打包到aar中的。gradle网络下载的文件的jar可以自行百度查看如何找到。



作者:Pieces_Jing
链接:https://www.jianshu.com/p/86b275da600e

我的:

对android stuido 不太熟,刚下载完新建一个项目就一堆错,慌得一B

后来发现

   classpath 'com.android.tools.build:gradle:3.2.1'
明明引用的是3.2.1,android 自动下载的却是gradle-4.6.0

C:\Users\gegx\.gradle\wrapper\dists\gradle-4.6-all

于是去网上下载了C:\Users\gegx\.gradle\wrapper\dists\gradle-3.2.1-all,顺利解决.

更多相关文章

  1. 优雅的构建 Android(安卓)项目之磁盘缓存(DiskLruCache)
  2. Android中Activity生命周期说明及使用
  3. 【Android的从零单排开发日记】之入门篇(五)——Android四大组件之
  4. Android小白进阶之路--项目需求2
  5. Android(安卓)Studio3.0开发JNI流程------JNI中字符串拼接的三种
  6. Android——Intent在Activity的使用详解-下(隐式Intent与实现调用
  7. Unity与Android通信优化方案
  8. 实战:Android活动目录LiveFolder开发
  9. android打开一个activity时,什么情况使用finish()

随机推荐

  1. Android(安卓)如何永久性开启adb 的root
  2. android build path contains duplicate
  3. Android(安卓)如何清空 Canvas ?(找了好
  4. Android热更新框架Nuwa的使用
  5. Android(安卓)TextView加上阴影效果
  6. android中延迟执行某个任务(基础备用)
  7. Android(安卓)里的FrameBuffer
  8. Android(安卓)2D游戏引擎AndEngine快速入
  9. android实体类的Parcelable
  10. Android(安卓)JNI小实例