Unity5.6.6 和 Android Studio 3.1.3 版本 Jar 包对接记录

由于产品硬件的原因,我们需要通过一个按钮去操控游戏,这个按钮是和安卓系统的一体机板卡直接通信的,经过资料的查阅,发现安卓系统的按钮端口开发和 pc 上的 windows 有所差别,是需要通过 android studio 进行开发的,所以只能通过jar包这种方式进行通信对接。为了和开发 jar 包的技术人员进行沟通,并且也是为了在 unity 里直接调用 jar 包做准备,所以我也需要了解下 unity 和安卓的对接方式。在此进行记录以便日后进行查阅。


Unity 项目配置

虽然看了很多文章都是先写的如何打 Jar 包然后才是和 Unity 的对接。但是实际过程中可能往往都是先有的 Unity 项目工程,之后才会根据特定的需要去对接 Android 系统。所以在此我优先记录的是 Unity 方面的准备工作。
由于我们的项目使用的是 Unity5.6.6 版本,所以测试工程我也同样使用此版本。

  1. 创建测试工程
    专门创建一个场景和相关的测试脚本,如下图所示:
    在这里插入图片描述
    在这里插入图片描述
    在这个场景中,我将通过 Jar 包调用两个测试方法。
    第一个方法演示了 Unity 调用 Android 的通信方式。
    第二个方法演示了 Android 调用 Unity 的通信方式。
    需要注意的是场景中的 “ObjJar” 这个对象,我将测试脚本挂在此对象身上。这个对象的名称可以自由定义,但是之后 Android 调用Unity的方法时将会检索这个对象的名称和其身上脚本内部的方法名。
    在这里插入图片描述
  2. 提前定义接口名
    我将提前确定好安卓端使用的接口名称。
    JarTest 内容如下:
using System;
using UnityEngine;
using UnityEngine.UI;

public class JarTest : MonoBehaviour {

    public Text MsgAndroid;
    public Text MsgUnity;

    private AndroidJavaClass mJc;
    private AndroidJavaObject mJo;

    private void Start()
    {
    	// 此处为了稳妥起见进行了一下异常处理判断
        try
        {
        	// 固定写法,获取当前安卓系统的上下文。
        	// 获得位于 com.unity3d.player 包下的 UnityPlayer 类
        	// 所谓上下文在我看来就相当于是Android中的当前运行的Scene
            mJc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

			// 获得 mJc 所代表的类下的 currentActivity 对象
        	// 相当于获取了之前制作的模块中的 MainActivity 类
            mJo = mJc.GetStatic<AndroidJavaObject>("currentActivity");
        }
        catch (Exception e)
        {
            MsgAndroid.text = string.Format("Error: {0}", e.ToString());
        }
    }
    
	/// <summary>
    /// 点击事件,调用 Jar 包中名为 “add” 的方法,并传入两个参数,获取int类型返回值
    /// </summary>
    public void BtnShowAndroidMsg()
    {
        int msg = mJo.Call<int>("add", 10, 19);
        MsgAndroid.text = string.Format("AndroidMsg: {0}", msg);
    }
    
    /// <summary>
    /// 点击事件,调用 Jar 包中名为 “UnityDebug” 的方法,此方法没有返回值
    /// </summary>
    public void BtnShowUnityMsg()
    {
        mJo.Call("UnityDebug");
    }
    
    /// <summary>
    /// 此方法为 Android 端将要调用的 Unity 中的方法
    /// </summary>
    /// <param name="msg"></param>
    public void JarDebug(string msg)
    {
        MsgUnity.text = string.Format("UnityMsg: {0}", msg);
    }
}
  1. 对 Unity 进行配置
    最后,顺便将工程转为安卓平台,并且配置下包名
    在这里插入图片描述
    至此 Unity 端的配置大致就结束了。

Jar 包生成

  1. 创建 Android Studio 工程
    在这里插入图片描述
    注意此处的包名其实可以和 Unity 工程的包名不同。
    在这里插入图片描述
    最小 API 要和 Unity 中设置的同步。
    在这里插入图片描述
    创建一个空工程。
    在这里插入图片描述
    在这里插入图片描述
    至此我们就成功的创建出一个安卓工程了。

在这里插入图片描述

  1. 创建 Module,添加 Unity 的 classes.jar
    虽然创建好的工程,但实际上我们并不会用到这个工程自带的场景。我们需要重新创建一个模块 (Module),并使用这个模块来制作 Jar 包。

在这里插入图片描述
在这里插入图片描述
给模块命名,注意的是此处的包名就是之后 Jar 包的包名,虽然网上有文章说需要将此处包名和 Unity 工程包名设置为相同。但经过测试实际此处包名可以自定义,并不需要和 Unity 包名相同。
在这里插入图片描述
到这里就创建了一个新的模块,此时我们需要确认下这个模块中的 build.gradle 中显示的是 “library” 才可以

在这里插入图片描述
之后在 Unity 的安装路径下找到 classes.jar 文件并导入到模块中的 libs 文件夹中。
不同的 Unity 版本 classes.jar 的目录可能不同,Unity5.6.6 中的位置如下:
Unity5.6.6\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

在这里插入图片描述
之后右键点击 classes.jar 选择 “Add As Library”。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 创建 Activity,并编写对接代码
    在这里插入图片描述
    勾选 Launcher Activity 选项,将此 Activity 默认为初始启动程序。
    在这里插入图片描述
    创建结束后,由于我不需要使用安卓的页面,所以把 layout 文件夹中的 xml 删除,同时删除 onCreate 方法中的 setContentView(R.layout.activity_main)。
    在这里插入图片描述
    删除后如图所示:
    在这里插入图片描述
    之后我们开始在 MainActivity 中编写代码。首先要引用 Unity 提供的 jar 包。同时让 MainActivity 继承 UnityPlayerActivity。
    在这里插入图片描述
package com.example.testjar;

import android.os.Bundle;

import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    // Unity 端调用的接口,返回参数 a+b 的和
    public int add(int a, int b){
        return a + b;
    }

    // Android 端调用 Unity 的接口
    public void UnityDebug(){
    	// 将会在 Unity 场景中搜索 ObjJar 这个对象名称,并且调用其身上脚本中的 JarDebug 方法,
    	// 传入一个 string 类型参数,如果不许要传参,此处就传一个空字符串
        UnityPlayer.UnitySendMessage("ObjJar", "JarDebug", "调用成功呢!");
    }
}
  1. 打 Jar 包

在结束以上工作之后,需要做的就是修改 testjar 模块中的 AndroidManifest 文件。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.testjar">

    <application>
        <activity android:name="com.example.testjar.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>

如图:
在这里插入图片描述
添加红框中的内容保证将此 Activity 设置为默认启动项,同时注意 activity 最好使用“包名”+“类名”的全名。在此处就是 “com.example.testjar.MainActivity”。
之后选中 testjar 文件夹,并点击 Build 选项中的 Make Module ‘testjar’,就可以生成 jar 包了。
在这里插入图片描述
不同 Android Studio 版本生成 jar 包的位置不同,当前 3.1.3 的位置如下
在这里插入图片描述


Unity 对接 Android

将生成的 Jar 包导入到Unity项目中如下目录,同时也将 AndroidManifest 文件导入。AndroidManifest.xml 相当于是一个比 Unity 中的 Player Settings 权限更高的配置文件,在 AndroidManifest 中设置的项目会覆盖掉 Player Settings 中的同种配置,例如:包名等。图中 assets 和 res 文件夹 都是放相应 Android 引用资源的,由于我们没有额外的引用,所以全都是空。
在这里插入图片描述
检查下Unity中脚本的引用之类的是否正确。按钮是否添加了监听。
没有问题之后打包测试!
在这里插入图片描述


总结

此次测试最大的一个需要引起关注的问题就是包名问题。由于查阅的网上资料大多都是说 Jar 包的包名要和Unity 项目包名一致,但是经过此次测试可以看出,
Unity 的包名是:
在这里插入图片描述
而Jar包的包名是:
在这里插入图片描述
实际运行是并没有出现问题,可以成功调用。所以可能需要留意的就是 AndroidManifest 这个问题件的配置。
在这里插入图片描述
可能是由于这个 activity 的 name 名称需要设置为相应引用的包名就可以正常调用 Jar 包了。具体原因由于时间等原因无法深究,如果以后有机会深入了解的话会继续补充。

猜你喜欢

转载自blog.csdn.net/EverNess010/article/details/88680887
今日推荐