Unity Android SDK 接入(一) - Unity 与 Android 交互

文章目录

    • Unity 和 Android 交互流程总结
    • API 详解
    • 概述
      • Unity 发布 Android 的基础概念
        • 关于 classes.jar
        • aar 和 jar 的区别
        • 关于 AndroidManifest
        • 关于 AndroidManifest 的合并
        • 发布 APK 的两种方式
      • Unity 接入 SDK 两种方法
      • 如何在 Unity 中调用 Android 的 java 代码
      • 如何在 Android 调用 Unity 的代码
    • SDK 接入的框架搭建
      • Android 需要的具体步骤
        • 新建 Android 项目
          • 利用 Android Libray Module
        • 复制 unity 的 classes 到 android
        • 新建 MainActivity
        • 导出 jar 或 arr
      • Unity 需要的具体步骤
        • 导入 jar/aar
        • AndroidManifest 文件
        • 编写界面和交互脚本
        • Build APK
        • 真机测试运行
    • 参考文章

Unity 和 Android 交互流程总结

  1. 将 Unity 安装目录下的 classes.jar 复制到 Android 项目的 libs 文件夹下
  2. Android 编写代码实现
  3. Android 导出 jar/aar
  4. unity 导入 jar/aar
  5. 利用 AndroidJavaClassAndroidJavaObject 调用相应的方法,实现功能

API 详解

  • AndroidJavaClass

    • public AndroidJavaClass(string className); // className:指定类名
    • 是 java.lang.Class 的一个通用实例的统一表示,是 java 里的类,适用于返回类型为“void”的静态方法。
  • AndroidJavaObject

    • 会生成一个对象,就和 java 里 new 一个对象一样,可以通过对象去调用里面的方法以及属性。
// 加载 com.td.sdktest.GameHelper 类
AndroidJavaClass jc = new AndroidJavaClass("com.td.sdktest.GameHelper");

// 实例化 com.td.sdktest.GameHelper 对象
AndroidJavaObject jo = new AndroidJavaObject("com.td.sdktest.GameHelper");

// 调用 com.td.sdktest.GameHelper 类中的 Test 静态方法
jc.CallStatic("Test");
jc.CallStatic("Test","Hello"); // 带参数的静态方法
int sum = jc.CallStatic("Sum", 1, 2); // 带参数和返回值的静态方法

//调用 com.td.sdktest.GameHelper 类中的 Test 实例方法
jo.Call("Test");
jo.Call("Test","Hello");
int sum = jo.Call("Sum", 1, 2);

概述

Unity 发布 Android 的基础概念

关于 classes.jar

Unity 发布 Android 的 APK 时,会使用 Android 的 SDK 进行构建,发布出来的 APK 只包含一个 Activity,俗称MainAcitivity,在发布过程中,Unity 会引入内置的 Jar 库(classes.jar),里面包含了 Unity 需要的库类,关键类 UnityPlayerActivity 就是 Android 程序的主要入口类,也就是 MainActivity。

aar 和 jar 的区别

jar:只包含了class文件与清单文件,不包含资源文件,如图片等所有 res 中的文件。

aar:包含所有资源,class 以及 res 资源文件全部包含。

关于 AndroidManifest

Unity 发布 Android 的 APK 时,如果在 Plugins/Android( Unity特殊目录 ),不存在 AndroidManifest 文件,会使用 Unity 默认的 AndroidManifest 文件。

默认的 AndroidManifest 文件目录在:Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Apk

如果存在 AndroidManifest 文件,那么 Unity 会使用它代替默认的 AndroidManifest 文件,这个AndroidManifest,必须带有活动以及标签。

Unity Android SDK 接入(一) - Unity 与 Android 交互_第1张图片

关于 AndroidManifest 的合并

Unity 发布 Android 的 APK 时,关于 AndroidManifest 的合并,分为两种情况

  • 不合并,导出 Jar 包时,Unity 只会识别 Plugins/Android 里的 AndroidManifest 作为描述清单或者使用默认的 AndrodManifest 文件,这时需要在描述清单需要添加权限,或其他服务,需要创建自定义的AndroidManifest,就是 Plugins/Android 目录下的 AndroidManifest 添加。

    Unity Android SDK 接入(一) - Unity 与 Android 交互_第2张图片

  • 合并,导出 Arr 包时,Arr 包里面会带有 AndroidManifest 文件,打开查看,里面的目录结构如下:

    Unity Android SDK 接入(一) - Unity 与 Android 交互_第3张图片

    • 在导出 APK 时,Unity 会解析 Arr 包的资源,并把它们的 AndroidManifest 文件合并到 Plugins/Android目录下的 AndroidManifest 文件或者 Unity 默认的 AndroidManifest 文件中,这样每个 Arr 包 的AndroidManifest 请求的权限或者服务最后会合并到一个 AndroidManifest 中。
      Unity Android SDK 接入(一) - Unity 与 Android 交互_第4张图片

发布 APK 的两种方式

  • Internal 不需要签名,仅需 Android SDK 支持,不能导出工程 ,适用于仅适用到 Unity 开发的项目
  • Gradle 需要签名(2017.3.x 之前的版本都需要), 需要 Android SDK 与 Gradle 支持,可以导出 Android Studio 工程,适用于需要与 Android 功能交互的的项目

Unity 接入 SDK 两种方法

Unity 接入 SDK 常用的方法有两种:

  1. 将 Unity 在安卓平台选择 Gradle 打包出来,然后在放在 AndroidStudio ,再导入需要的 SDK 进行操作。

  2. 将 Unity 的 classes.jar 包和需要的 SDK 导入 AndroidStudio 新建的 Library 中,然后在导出 jar 或 aar 放到Unity 中去调用。(常用)

重要的是要学会 android 怎么调用 Unity 里的方法,Unity 怎么调用 android 里的方法。

如何在 Unity 中调用 Android 的 java 代码

需要先把 android 代码打包成 jar 包(或 arr 包),然后将该 jar 包引入到 Unity 工程。

然后通过 AndroidJavaClassAndroidJavaObject 进行调用。

如何在 Android 调用 Unity 的代码

在场景中创建一个游戏物体并挂载一个用于交互的脚本,Android 调用 GameObject 交互脚本上的方法,来实现相应的功能。

SDK 接入的框架搭建

Android 需要的具体步骤

在 Android 端编写代码,利用 SDK 实现具体的功能,将这些功能封装成方法,最后导出 jar 或 arr 包,将包导入 Unity,最后在 Unity 里实现调用。

可以直接新建一个 Android 项目进行编写,也可以创建一个 Libray 模块进行编写,任选其一即可。

新建 Android 项目

利用 Android Libray Module

File -> New -> New Module -> Android Libray

Unity Android SDK 接入(一) - Unity 与 Android 交互_第5张图片

复制 unity 的 classes 到 android

Unity 和 Android 做交互,他们两个之间不认识肯定,没法直接通信,因此需要一个中间的搭桥牵线的人,Classes.jar 就起到了这个作用。Classes.jar 是由 Unity 提供给我们的,我们需要找到它并且引入到我们的Android 项目中。

将 Unity 安装目录下的 classes.jar 复制到 Android 项目的 libs 文件夹下(建议改名后复制,方便辨认和管理),并添加依赖。

D:\Unity\2018.4.2f1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

该目录可能不同,可以直接在安装目录下搜索 Classes.jar

Unity Android SDK 接入(一) - Unity 与 Android 交互_第6张图片

新建 MainActivity

编写一个静态函数,和一个普通函数,供 Unity 调用

package com.td.sdkaccess;

import android.os.Bundle;
import com.unity3d.player.*; // 复制过来的 unity_classes.jar

public class MainActivity extends UnityPlayerActivity { // 注意是 UnityPlayerActivity

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    /**
     * 供 Unity 调用的求和函数(静态)
     */
    public static int Sum(int x, int y) {
        return x + y;
    }
    
    /**
     * 供 Unity 调用的显示吐司的函数
     */
    public void MakeToast(String str) {
        Toast.makeText(this, str, Toast.LENGTH_LONG).show();
    }
}

导出 jar 或 arr

  • 如果是之前是直接使用 app 项目,导出 jar,需要做如下配置,如果使用的是 Libray Module 则不需要。

    • app 项目:修改 app 下的 build.gradle 文件

      //apply plugin: 'com.android.application'
      apply plugin: 'com.android.library' // 不生成 apk,生成 jar/aar 包
      
      android {
          defaultConfig {
              // applicationId "com.td.sdktest"  注释这一行
              ...
          }
      ...
      // 方便操作,复制 jar 到指定位置,在 Termanil 窗口使用输入命令 gradlew makejar
      task makeJar(type:Copy){
          delete 'build/libs/sdk.jar'
          from('build/intermediates/bundles/release/')
          into('build/libs/')
          include('classes.jar')
          rename('classes.jar','sdk.jar')
      }
      
  • Build -> Rebuild Project

  • 到相应目录查看 jar/aar,(android studio 版本不同,输出目录可能不一样)

    Unity Android SDK 接入(一) - Unity 与 Android 交互_第7张图片

Unity 需要的具体步骤

导入 jar/aar

将 Android 导出的 jar 或 aar 复制到项目 Plugins/Android 目录下

如果导入的是 aar,有以下几点需要注意:

  • 删除 unity_classes.jar 冲突文件,在 aar 的 lib 里
  • 删除包根目录下面的 Android 配置文件(先复制一份出来)
  • 删除 aar 跟目下的 classes.jar 里面的 BuildConfig.class 文件

其实不清楚这 3 步是否是必须的,但是因为各种花式报错,最后经验证通过这三步可以解决。

AndroidManifest 文件

这里可以使用 Unity 导出,然后使用里面的 AndroidManifest 文件进行修改。

Unity Android SDK 接入(一) - Unity 与 Android 交互_第8张图片

Unity Android SDK 接入(一) - Unity 与 Android 交互_第9张图片

根据自己的项目,修改 AndroidManifest 文件


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.td.sdkbase"
    android:versionCode="1"
    android:versionName="1.0" > 

  <uses-sdk
      android:minSdkVersion="16"
      android:targetSdkVersion="29" />

  <application
        android:allowBackup="true"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Light.NoTitleBar">
      <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>

编写界面和交互脚本

在场景中创建物体用于挂载与 Android 交互的脚本。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MainPanel : MonoBehaviour {
    private AndroidJavaClass _jc;
    private AndroidJavaObject _jo;
    public Text resultLabel;

    void Start() {
        // 获取 Unity 导出的 Activity 对象,固定写法,UnityPlayerActivity 里面对其进行了处理
        _jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); // Unity 要导出的 MainActivity 类
        _jo = _jc.GetStatic("currentActivity"); // 获取 MainActivity 的实例对象
    }

    public void Sum() {
        AndroidJavaClass jc = new AndroidJavaClass("com.td.sdkbase.MainActivity"); // 加载自己的类,指定实现了需要调用相应方法的类
        resultLabel.text = "Sum:" + jc.CallStatic("Sum", 1, 5); // 调用 Java 类中的静态方法 Sum,返回值为 int 型,参数 1,5
    }

    public void Toast() {
        _jo.Call("MakeToast", "Unity 调用 Android,显示 Toast");  // 调用 Java 类中的普通方法
    }
}

Build APK

注意修改包名

Unity Android SDK 接入(一) - Unity 与 Android 交互_第10张图片

真机测试运行

Unity Android SDK 接入(一) - Unity 与 Android 交互_第11张图片

参考文章

【Unity游戏开发】SDK接入与集成——小白入门篇

Unity与Android——Androidmanifest.xml文件的介绍

Unity与Android交互-扩展Unity的MainActivity

SDK接入基础演示

你可能感兴趣的:(Unity3D)