Unity3d接入安卓aar详细过程

Unity3d接入安卓aar详细过程

unity 在开发过程中,往往需要安卓端暴漏一些原生的接口,比如权限,广播,获取一些设备信息等接口。这时候就需要用到各自的知识,但是相对跨行,很多门外unity 程序员 或者 安卓程序员并不会搭建环境,也不会生成aar 供unity 调用,现总结如下,这些将教会你从安卓端生成aar 到unity 运行,最终安卓端与unity 相互配合调用。

内容点

  • 搭建环境(安卓端生成aar,unity 建立plugin 并放入aar 和 manifest 并且可以安卓平台打包生成apk)
  • Unity 调用安卓端方法
  • 安卓通过回调发送信息给 Unity

搭建环境

  1. 新建一个安卓工程(因为用默认的app 修改,需要改一些东西,所以不用它,新建一个Module 见下文)
    1.1 New Module 为 Android Library 库 这里需要记住 包名,后面unity 需要配置相同
    1.2 拷贝 Unity 安装目录下的 class.jar 文件 到安卓 libs 下,路径如(C:\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes),并添加依赖
    1.3 包下 新建 activity 不需要勾选布局,勾选启动activity,修改 SplashActivity 继承 UnityPlayerActivity
public class SplashActivity extends UnityPlayerActivity {

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

    //新增方法供unity 调用
    public int Add(int a,int b) {
        return  a+b;
    }
}
1.4 修改 库的gradle 文件,因为unity 不支持在线库,所以用到的库,需要unity 也放置一份,避免冲突,需要删除不必要的库,以及 修改库的引用方式 为 “ compileOnly “  修改完同步(Sync)

Unity3d接入安卓aar详细过程
1.5 修改 AndroidManifest.xml 为以下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testlibrary">
    <application
        android:allowBackup="true"
        android:label="安卓"
        android:supportsRtl="true">
        <activity android:name=".SplashActivity">
            <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>
1.6 编译生成 aar  (gradle->xxxlibrary->Tasks->build->assemble 双击)   【生成jar 不用看 只需要了解】
compileOnly fileTree(include: ['*.jar'], dir: 'libs')
compileOnly files('libs/classes.jar')

编译生成jar (jar 与aar 区别,不包含引用的res 资源文件 ,选中library  Build-> Make Module 'xxxlibrary')
如果没使用compileOnly方式引用,需要 解压jar,删除lib下的 class.jar 文件 (若class.jar 修改为 compileOnly  就不需要删除了 ,直接引用即可 )
compileOnly fileTree(include: ['*.jar'], dir: 'libs')
compileOnly files('libs/classes.jar')
  1. 新建Unity 项目, Asserts 下 新建文件夹 Plugins\Android
  2. 拷贝生成的 AndroidManifest.xml 和 testlibrary-debug.aar 到 Unity 项目路径Plugins\Android 下面
  3. Unity 声明 脚本,绑定在obj 上面,然后 加入 text 组件
public class Test : MonoBehaviour
{
    public Text text;
    // Start is called before the first frame update
    void Start()
    {
        AndroidJavaClass AJC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject AJO = AJC.GetStatic<AndroidJavaObject>("currentActivity");
        text.text = AJO.Call<int>("Add", 10, 30).ToString();
    }

    // Unity 监听手机按返系统回键
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape)) {
            Application.Quit();
        }
    }
}
  1. 设置 build 安卓的包名 和 aar 的 manifest 一致
  2. 打包生成apk

Unity 调用安卓端方法


Unity

        //调用继承unityplayerActivity 的 安卓activity 的非静态方法
        AndroidJavaClass jclass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jcontext = jclass.GetStatic<AndroidJavaObject>("currentActivity");
        text.text = jcontext.Call<int>("add", 10, 30).ToString();
        //调用继承unityplayerActivity 的 安卓activity 的 静态方法
        AndroidJavaClass jclass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jcontext = jclass.GetStatic<AndroidJavaObject>("currentActivity");
		//根据包名 和 类名 找到 对象,分 AndroidJavaClass  和  AndroidJavaObject (两者 是有区别的)
        AndroidJavaClass loginObject = new AndroidJavaClass("pers.study.android2unity.SplashActivity");
        // AndroidJavaClass  可以直接掉static 方法 ,不可以调用普通非静态方法
        loginObject.CallStatic("showToast", jcontext); //给安卓传过去context 
		//调用普通 class  的 安卓静态方法
        AndroidJavaObject helper = new AndroidJavaObject("pers.study.android2unity.Helper");
         // AndroidJavaObject 可以直接掉static 方法 ,也可以调用普通非静态方法
        helper.CallStatic("getMessageFormUnity", "我是 unity ===");

Android

public class SplashActivity extends UnityPlayerActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    //新增方法供unity 调用
    public int add(int a,int b) {
        return  a+b;
    }
    //新增方法供unity 调用
    public static void showToast(Context context) {
        Toast.makeText(context, "安卓发起 土司", Toast.LENGTH_SHORT).show();
    }
}

package pers.study.android2unity;
public class Helper {
    /**
     * 这个方法 可由Unity 某个条件出发,然后由 安卓端处理数据 再返回 unity;也可以安卓端主动调用,发送消息给 unity
     * @param json
     */
    public static void getMessageFormUnity(String json){
        setLoginResponseToUnity(json.replace("unity","android"));
    }
}
到这里,unity 调用安卓的几种方法都介绍了。最后最好将 new AndroidJavaObject 类似的方法写道Unity 的一个单独脚本里做单例处理。另外要注意AndroidJavaClass 与 AndroidJavaObject 的不同,前者只能掉静态方法。

安卓通过回调发送信息给 Unity

  • 定义安卓接口(一个大的项目不可能只有一个安卓回调,所以可以分类使用同一个回调接口,然后根据定义参数)
package pers.study.android2unity;
public interface AndroidSendMessageToUnityListener {
    /**
     * 定义接口返回格式 可自定义 可以定义json  自己解析
     * @param json
     */
    void OnCallback(String json);
}
  • 定义安卓方法绑定接口
package pers.study.android2unity;
import android.util.Log;
public class Helper {
    //这里如果不写 静态 就写为 单例 一样的
    private static AndroidSendMessageToUnityListener listener;
    public void setAndroudForUntiyListener(AndroidSendMessageToUnityListener listener2) {
        this.listener = listener2;
    }
    //当untiy 绑定了接口后 就可以发送消息到 unity 了
    public static void setLoginResponseToUnity(String json){
        if (listener != null) {
            listener.OnCallback(json);
        }
    }
    /**
     * 这个方法 可由Unity 某个条件出发,然后由 安卓端处理数据 再返回 unity;也可以安卓端主动调用,发送消息给 unity
     * @param json
     */
    public static void getMessageFormUnity(String json){
        setLoginResponseToUnity(json.replace("unity","android"));
    }
}
  • 定义Untiy接口
using System;
using UnityEngine;
public class AndroidSendMessageToUnityListener : AndroidJavaProxy
{
    private Action<string> callback;
    public AndroidSendMessageToUnityListener(Action<string> callback) : base("pers.study.android2unity.AndroidSendMessageToUnityListener")
    {
        this.callback = callback;
    }
    public void OnCallback(string json) {
        if (callback != null)
        {
            callback(json);
        }
    }
}
  • Unity 绑定接口并接口安卓回传信息
using System;
using UnityEngine;
using UnityEngine.UI;
public class TestAndroid : MonoBehaviour
{
    public Text text;
    public Button button;
    public Text text2;

    public AndroidSendMessageToUnityListener listener;

    void Start()
    {
        if (listener == null) {
            listener = new AndroidSendMessageToUnityListener(CallBack);
        }
        AndroidJavaObject helper = new AndroidJavaObject("pers.study.android2unity.Helper");
        helper.Call("setAndroudForUntiyListener", listener);
        button.onClick.AddListener(SendMsg);
    }

    private void SendMsg()
    {
        AndroidJavaObject helper = new AndroidJavaObject("pers.study.android2unity.Helper");
        helper.CallStatic("getMessageFormUnity", "我是 unity ===");
    }
    private void CallBack(string json)
    {
        if (!String.IsNullOrEmpty(json)) {
            text2.text = json;
        }
    }
    private void OnDestroy()
    {
        button.onClick.RemoveListener(SendMsg);
    }
}

到此,Unity 接入安卓aar 基本结束。这是对自己新的跳转,期间遇到了很多坑。好比人生,一次次将你击败,你再一次次站起来。

Unity3d接入安卓aar详细过程
Unity3d接入安卓aar详细过程
附上项目地址 :Github Demo
欢迎点赞和留言

上一篇:三维性能优化总结篇 02 之3D模型制作流程


下一篇:Unity3D直播播放器SDK