AndroidJavaClass
和 AndroidJavaObject
调用相应的方法,实现功能AndroidJavaClass
public AndroidJavaClass(string className); // className:指定类名
AndroidJavaObject
// 加载 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 的 APK 时,会使用 Android 的 SDK 进行构建,发布出来的 APK 只包含一个 Activity,俗称MainAcitivity,在发布过程中,Unity 会引入内置的 Jar 库(classes.jar),里面包含了 Unity 需要的库类,关键类 UnityPlayerActivity 就是 Android 程序的主要入口类,也就是 MainActivity。
jar:只包含了class文件与清单文件,不包含资源文件,如图片等所有 res 中的文件。
aar:包含所有资源,class 以及 res 资源文件全部包含。
Unity 发布 Android 的 APK 时,如果在 Plugins/Android( Unity特殊目录 ),不存在 AndroidManifest 文件,会使用 Unity 默认的 AndroidManifest 文件。
默认的 AndroidManifest 文件目录在:Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Apk
如果存在 AndroidManifest 文件,那么 Unity 会使用它代替默认的 AndroidManifest 文件,这个AndroidManifest,必须带有活动以及标签。
Unity 发布 Android 的 APK 时,关于 AndroidManifest 的合并,分为两种情况
不合并,导出 Jar 包时,Unity 只会识别 Plugins/Android 里的 AndroidManifest 作为描述清单或者使用默认的 AndrodManifest 文件,这时需要在描述清单需要添加权限,或其他服务,需要创建自定义的AndroidManifest,就是 Plugins/Android 目录下的 AndroidManifest 添加。
合并,导出 Arr 包时,Arr 包里面会带有 AndroidManifest 文件,打开查看,里面的目录结构如下:
Unity 接入 SDK 常用的方法有两种:
将 Unity 在安卓平台选择 Gradle 打包出来,然后在放在 AndroidStudio ,再导入需要的 SDK 进行操作。
将 Unity 的 classes.jar 包和需要的 SDK 导入 AndroidStudio 新建的 Library 中,然后在导出 jar 或 aar 放到Unity 中去调用。(常用)
重要的是要学会 android 怎么调用 Unity 里的方法,Unity 怎么调用 android 里的方法。
需要先把 android 代码打包成 jar 包(或 arr 包),然后将该 jar 包引入到 Unity 工程。
然后通过 AndroidJavaClass
和 AndroidJavaObject
进行调用。
在场景中创建一个游戏物体并挂载一个用于交互的脚本,Android 调用 GameObject 交互脚本上的方法,来实现相应的功能。
在 Android 端编写代码,利用 SDK 实现具体的功能,将这些功能封装成方法,最后导出 jar 或 arr 包,将包导入 Unity,最后在 Unity 里实现调用。
可以直接新建一个 Android 项目进行编写,也可以创建一个 Libray 模块进行编写,任选其一即可。
File -> New -> New Module -> Android Libray
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 调用
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();
}
}
如果是之前是直接使用 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 版本不同,输出目录可能不一样)
将 Android 导出的 jar 或 aar 复制到项目 Plugins/Android 目录下
如果导入的是 aar,有以下几点需要注意:
其实不清楚这 3 步是否是必须的,但是因为各种花式报错,最后经验证通过这三步可以解决。
这里可以使用 Unity 导出,然后使用里面的 AndroidManifest 文件进行修改。
根据自己的项目,修改 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 类中的普通方法
}
}
注意修改包名
【Unity游戏开发】SDK接入与集成——小白入门篇
Unity与Android——Androidmanifest.xml文件的介绍
Unity与Android交互-扩展Unity的MainActivity
SDK接入基础演示