Unity和Android的交互

Unity和Android的交互

  • 一、前言
  • 二、Android导出jar/aar包到Unity
    • 2.1 版本说明
    • 2.2 拷贝Unity的classes.jar给Android工程
      • 2.2.1 classes.jar的位置
      • 2.2.2 Android Studio创建module
      • 2.2.3 拷贝classes.jar 到 Android工程并启用
    • 2.3 编写Android工程代码
      • 2.3.1 创建 MainActivity
      • 2.3.2 MainActivity改继承 UnityPlayerActivity
      • 2.3.3 拷贝 UnityPlayerActivity
      • 2.3.4 编写Android工程代码
      • 2.3.5 编写AndroidManifest.xml
    • 2.4 编写Unity工程代码
      • 2.4.1 搭建游戏物体GameObject
    • 2.5 导出和构建APK
      • 2.5.1 导出Java文件
      • 2.5.2 导出Jar包
        • 2.5.2.1 构建Jar包
        • 2.5.2.2 新建Task任务构建和重命名Jar包
      • 2.5.3 导出aar包
        • 2.5.3.1 构建aar和修改aar包
        • 2.5.3.2 压缩aar包细节
        • 2.5.3.3 解决Androidmainfest合并问题
        • 2.5.3.4 解决桌面2个启动图标

一、前言

Unity和Android原生交互的方式大概有2种,一种是Android导出jar/aar包给Unity,然后Unity来构建apk;另外一种是Unity勾选Export Project,导出为一个Android工程,然后用AndroidStudio构建APK;这里讲讲第一种方式

二、Android导出jar/aar包到Unity

2.1 版本说明

  • 这里我用的Unity版本是 2020.3.33f1c2; AndroidStudio 用的版本是 2021.3.1
    思路大致是一致的,但不同版本可能导出的文件路径不太一样或内容可能不太一样,这个要注意一下

2.2 拷贝Unity的classes.jar给Android工程

2.2.1 classes.jar的位置

classes.jar 位于 {Unity 安装位置}\Editor\Data\PlaybackEngines\AndroidPlayer\Variations{mono或il2cpp}\Release\Classes\ 目录下

  • 这里主要涉及到2个变量,一个是Unity版本,一个是mono或il2cpp;
    不同Unity版本的安装路径不一样,可以用UnityHub点击 设置按钮-在资源管理中显示。快速进入到对应版本的目录;
    在这里插入图片描述
    至于mono或il2cpp,主要看你选用哪种打包方式。由于是示例空工程,并且要快速构建,所以我这里选了mono;

2.2.2 Android Studio创建module

先用Android Studio新建一个Android Studio空工程,接着我们创建一个module模块来实现功能
点击 File-New-New Module,拉起创建面板
在这里插入图片描述
注意,这里要先切换到Android Library页签,然后可以输入你喜欢的module名字
在这里插入图片描述

2.2.3 拷贝classes.jar 到 Android工程并启用

  • 拷贝第一步的classes.jar,并粘贴进模块的libs目录下
    在这里插入图片描述
  • 启用classes.jar
    粘贴进来后,其实还没起作用。右键classes.jar,然后点击 Add as Library
    在这里插入图片描述
    然后你会发现classes.jar有个三角标了,这时才起作用了。
    在这里插入图片描述
    Add as Library 这一步操作等同于在module的build.gradle里添加 implementation files(‘libs\classes.jar’), 然后 点击 File - Sync Project with Gradle Files按钮;
    我们也可以通过修改文件的方式来快速的添加和移除lib
    在这里插入图片描述

2.3 编写Android工程代码

2.3.1 创建 MainActivity

在模块下创建MainActivity ,也不一定要这个名字,可以根据你喜欢的来
在这里插入图片描述

2.3.2 MainActivity改继承 UnityPlayerActivity

这里MainActivity 改继承自UnityPlayerActivity,不出意外,改继承后这里会报红。这是因为新版本的Unity(大概是2019和之后的版本),导出的 classes.jar 不再包含 UnityPlayerActivity了。所以我们需要再拷贝一个UnityPlayerActivity过来
在这里插入图片描述

2.3.3 拷贝 UnityPlayerActivity

这个路径在对应Unity版本的 Editor\Data\PlaybackEngines\AndroidPlayer\Source\com\unity3d\player目录下。只要找到前面的classes.jar,相信这个对你来说也是轻松找到
在这里插入图片描述

  • 拷贝进Android工程
    如下图,可以保持和MainActivity同级,拷贝进来
    在这里插入图片描述
    然后修改package路径(可以从MainActivity.java里拷贝package路径粘贴进来)和 引入命名空间
    代码如下,熟悉的朋友也可以在报红处按下Alt + Enter,手动引入
package com.example.linkunitylibrary; //这里拷贝你MainActivity的package
//import导入依赖
import com.unity3d.player.IUnityPlayerLifecycleEvents;
import com.unity3d.player.MultiWindowSupport;
import com.unity3d.player.UnityPlayer;

然后 MainActivity就不报红了
在这里插入图片描述

  • 题外话
    记得好像有些教程是放在com.unity3d.player目录下,并保持原包名,如下图的层级和package路径。我有测试过,但在最后构建apk会报错。
    在这里插入图片描述
  • 原因我觉得是这样:因为最终我们要把android studio构建出来的jar包或aar包,放回unity。那如果这里保持一样的包名,到时放回unity,就相当于有2个一样的 com.unity3d.player.UnityPlayerActivity 类了,那就会报错。所以我觉得这种方式应该不可行…

2.3.4 编写Android工程代码

这里我们分别 写一个方法给Unity调用 和 调用Unity里的一个方法
在这里插入图片描述
代码如下

package com.example.linkunitylibrary;
import android.os.Bundle;
import com.unity3d.player.UnityPlayer;/*** Created by super41 on 2024/4/5.*/
public class MainActivity extends UnityPlayerActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//调用Unity的方法a2u_add(1,5);}//写一个方法给Unity调用public int u2a_add(int a,int b){return a + b;}//调用unity里的方法public void a2u_add(int a,int b){sendMsg2Unity("a2u_add",a+"|"+b);}private static final String LinkGameObjectName  = "UnityLinkAndroidGo";/*** 给Unity发消息* @param methodName 方法名* @param params 参数*/private void sendMsg2Unity(String methodName,String params){//依次传入 GameObjectName, GameObject里的方法,参数//因为这里 GameObjectName 一般固定,所以封装起来//只能传递一个参数,多个参数拼接在params里UnityPlayer.UnitySendMessage(LinkGameObjectName,methodName,params);}
}

2.3.5 编写AndroidManifest.xml

修改AndroidManifest.xml,这里记得替换为你自己的包名和类名

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"><applicationandroid:allowBackup="true"android:supportsRtl="true"><activity android:name="com.example.linklibrary.MainActivity" android:exported="true"> <!--包名和类名,这里换成你自己的包名和类名--><intent-filter><action android:name="android.intent.action.MAIN" /> <!--主入口Activity--><category android:name="android.intent.category.LAUNCHER" /> <!--添加到桌面--></intent-filter><meta-data android:name="unityplayer.UnityActivity" android:value="true" /></activity></application></manifest>

2.4 编写Unity工程代码

2.4.1 搭建游戏物体GameObject

  • 创建2个Text文本,一个显示Unity_Call_Android的加法结果,一个显示Android_Call_Android的加法结果
    在这里插入图片描述
  • 创建UnityLinkAndroidGo物体,这里游戏名字要跟Android代码里的物体名字一致。
    创建任意名字的脚本,如UnityLinkAndroidScript,代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class UnityLinkAndroidScript : MonoBehaviour
{public Text Txt1;public Text Txt2;// Start is called before the first frame updatevoid Start(){u2a_add(100,200);}/// <summary>/// Unity调用Android/// </summary>void u2a_add(int a, int b){//标准操作,获取MainActivity对象AndroidJavaClass javaClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");AndroidJavaObject javaObject = javaClass.GetStatic<AndroidJavaObject>("currentActivity");//调用方法var result = javaObject.Call<int>("u2a_add", a, b);Txt1.text = $"UnityCallAndroid {a} + {b} = {result}";}/// <summary>/// 给android调用的方法/// </summary>/// <param name="objs"></param>void a2u_add(string objs){var arrays = objs.Split('|');var a = int.Parse(arrays[0]);var b = int.Parse(arrays[1]);var result = a + b;Txt2.text = $"AndroidCallUnity {a} + {b} = {result}";}}

然后把2个Text附上
在这里插入图片描述

2.5 导出和构建APK

一切准备就绪,接下来就是导出和构建APK了

2.5.1 导出Java文件

我们一般是导出jar包和aar包文件。其实也可以用导出java文件的方式
如下图,3个文件导出到Unity的Assets/Plugins/Android/目录下,如没有目录则创建
在这里插入图片描述
在这里插入图片描述
接着就是常规的构建apk了。我们来看运行结果。可以看到成功运行了起来
在这里插入图片描述

2.5.2 导出Jar包

2.5.2.1 构建Jar包

上面的导出java文件一般不是主流的方式,还是导出成一个压缩包的形式更好管理一点。我们来看看怎么导出jar包
选中你的module,然后点击 Build - Make Module xxx. 然后打开资源管理器,就可以看到这里生成了一个build目录
在这里插入图片描述
进入build\intermediates\aar_main_jar\debug\目录(这里不同Android版本可能输出路径不一样,思路是一致的)
可以找到classes.jar
在这里插入图片描述
拷贝这里的classes.jar拷贝到Plugins/Android/目录下,并删除掉原来的java文件。如下图
在这里插入图片描述
然后就是构建apk了,也可以得到我们想要的效果;

2.5.2.2 新建Task任务构建和重命名Jar包
  • 一般我们需要重命名我们的jar包,不然叫classes.jar不太好,手动改每次都要来一遍不太好。我们可以添加task任务来实现这一步骤。打开module的build.grade,在文件的最后添加任务

在这里插入图片描述
代码如下:

//删除旧jar包
task tryDeleteOldJar(type:Delete){delete('release/HelloWorld.jar')
}//导出并重命名jar包
task exportJar(type : Copy){from('build\\intermediates\\aar_main_jar\\debug')//从这个路径拷贝into('release') //拷贝到这个路径include('classes.jar')rename('classes.jar','HelloWorld.jar')
}//添加依赖
exportJar.dependsOn(tryDeleteOldJar,build)

然后Sync刷新一下
在这里插入图片描述
点击右侧的Gradle,然后点击Task/other
在这里插入图片描述
就可以看到exportJar任务了
在这里插入图片描述
双击执行它,我们可以得到一个重命名好的HelloWorld.jar
在这里插入图片描述
如果看不到Task任务,那是一些版本的AndroidStudio隐藏掉了,可以进入File-Setting-Experimental,然后取消勾选这个Do not build… 选项,然后点击OK后你就可以看到Task了(当然不同版本可能设置不一样,这里主要介绍一种解决思路)
在这里插入图片描述
到此,导出Jar包的形式也好了

2.5.3 导出aar包

我们还可以导出aar包,aar和jar包的区别是,jar包一般只包含java文件,而aar包除此之外,还可以包含res和AndroidMainfest.xml

2.5.3.1 构建aar和修改aar包

接下来我们来实现导出aar包;
和之前一样,我们选中Module,点击Build-Make Module来构建
在这里插入图片描述
可以在build/outputs/aar里面找到aar
在这里插入图片描述
aar包本质上是一个压缩包,我们改为.zip格式,然后用压缩文件打开。目录大致如下
在这里插入图片描述
还记得我们从unity拷贝了一个classes.jar过来嘛,这个文件也会被构建进aar包,然后当我们把aar包放回unity,那么就会有重名的类。所以我们需要删除掉这个classes.jar
在这里插入图片描述
具体的操作方式是:
把libs里的classes.jar删掉,然后箭头的classes.jar拖进libs目录
在这里插入图片描述

2.5.3.2 压缩aar包细节

然后接下来就是重新压缩成一个aar包了。压缩这里有2点很关键,我当时自己也是踩坑了好几个小时。
现在说一下:

  • 选中你的文件列表,然后右键进行压缩,如下图。注意不要在外层目录压缩,不然会多嵌套一层文件夹,导致Unity识别不到;
    在这里插入图片描述
  • 压缩格式这里选zip,不要选默认的rar… 当时就是选rar,然后就进坑了…
    在这里插入图片描述
    然后把得到的压缩包改为aar后缀
    在这里插入图片描述
    然后放回Unity,因为aar包已经有了AndroidMainfest.xml,所以可以把之前的删掉,只留下aar包
    在这里插入图片描述
    接下来就是构建出APK了,也可以得到我们想到的效果;
2.5.3.3 解决Androidmainfest合并问题

如果构建过程中提示AndroidMainfest 合并失败,如下图。是因为最小sdk版本要改一下
在这里插入图片描述
这里你可以对aar包里的minSdkVersion进行修改,改成提示的版本,比如我这里是改成19,然后导出为压缩包
在这里插入图片描述
也可以对Modudle的build.gradle改下minsdk版本,我这里是改成19,这种方式更好一点。然后重新构建aar包
在这里插入图片描述

2.5.3.4 解决桌面2个启动图标

使用导出aar的方式构建出的apk,桌面上可能会有2个程序入口,也就是2个图标。
我们需要修改下AndroidMainfest.xml
进入PlayerSetting,勾选 CustomMainfest.xml
在这里插入图片描述
然后会自动生成AndroidMainfest.xml
在这里插入图片描述
进入AndroidMainfest.xml,把这个activity整段删掉,然后再构建apk即可
在这里插入图片描述

最后导出APK就可以了。至此我们就完成了3种导出方式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/299515.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot之mybatisPlus多表查询及分页查询

文章目录 一、多表查询二、mybatis-plus条件查询三、分页查询 一、多表查询 可能会用到的注解 这里的场景是&#xff0c;查询每个用户及其所有的订单。就是查询你的id号的同时&#xff0c;把你所有的历史订单信息都拉出来。 表结构这样 CREATE TABLE User ( id INT PRIMARY…

施耐德中高端PLC仿真器

参考文档&#xff1a;《Unity Pro PLC 仿真器》EIO0000001719.06 &#xff08;Control Expert 就是 Unity Pro 最新版本换了个名字&#xff0c;两者操作基本相同&#xff09; https://www.schneider-electric.cn/zh/download/document/EIO0000001719/ 1. 适用 PLC 这里使用的…

TiDB 组件 GC 原理及常见问题

本文详细介绍了 TiDB 的 Garbage Collection&#xff08;GC&#xff09;机制及其在 TiDB 组件中的实现原理和常见问题排查方法。 TiDB 底层使用单机存储引擎 RocksDB&#xff0c;并通过 MVCC 机制&#xff0c;基于 RocksDB 实现了分布式存储引擎 TiKV&#xff0c;以支持高可用分…

计算机网络——37认证

认证 目标&#xff1a;Bob需要Alice证明他的身份 Protocol ap1.0&#xff1a;Alice说"A am Alice" 可能出现的问题&#xff1a; 在网络上Bob看不到Alice&#xff0c;因此Trudy可以简单的声称他是Alice 认证&#xff1a;重新尝试 Protocol ap2.0&#xff1a;Alice…

阿里云4核8G服务器ECS通用算力型u1实例优惠价格

阿里云4核8G服务器优惠价格955元一年&#xff0c;配置为ECS通用算力型u1实例&#xff08;ecs.u1-c1m2.xlarge&#xff09;4核8G配置、1M到3M带宽可选、ESSD Entry系统盘20G到40G可选&#xff0c;CPU采用Intel(R) Xeon(R) Platinum处理器&#xff0c;阿里云活动链接 aliyunfuwuq…

批量导入svg文件作为图标使用(vue3)vite-plugin-svg-icons插件的具体应用

目录 需求svg使用简述插件使用简述实现安装插件1、配置vite.config.ts2、src/main.ts引入注册脚本3、写个icon组件4、使用组件 需求 在vue3项目中&#xff0c;需要批量导入某个文件夹内数量不确定的svg文件用来作为图标&#xff0c;开发完成后能够通过增减文件夹内的svg文件&a…

一文解析智慧城市,人工智能技术将成“智”理主要手段

长期以来&#xff0c;有关智慧城市的讨论主要围绕在技术进步方面&#xff0c;如自动化、人工智能、数据的公开以及将更多的传感器嵌入城市以使其更加智能化。实际上&#xff0c;智慧城市是一个关于未来的设想&#xff0c;其重要原因在于城市中存在各种基础设施、政治、地理、财…

测试框架pytest学习与实践

pytest是一个专业的测试框架&#xff0c;可以帮助我们对python项目进行测试&#xff0c;提高测试的效率。 pytest官网手册&#xff1a;pytest: helps you write better programs — pytest documentation 中文手册&#xff1a;Pytest 教程 入门学习 安装pytest pip install…

代码随想录算法训练营第二十五天| 216.组合总和III、17.电话号码的字母组合

系列文章目录 目录 系列文章目录216.组合总和III17.电话号码的字母组合回溯法 216.组合总和III 本题k相当于树的深度&#xff0c;9&#xff08;因为整个集合就是9个数&#xff09;就是树的宽度。 剪枝&#xff1a;①for循环的范围剪枝&#xff0c;i < 9 - (k - path.size()…

Mac资源库的东西可以删除吗?mac资源库在哪里打开 cleanmymacx是什么 cleanmymac免费下载

在使用Mac电脑的过程中&#xff0c;用户可能会遇到存储空间不足的问题。一种解决方法是清理不必要的文件&#xff0c;其中资源库&#xff08;Library&#xff09;文件夹是一个常被提及但又让人迷惑的目标。Mac资源库的东西可以删除吗&#xff1f;本文旨在解释Mac资源库的作用、…

卫星遥感影像如何选择合适的分辨率

​ 卫星遥感影像的分辨率是影响其应用效果的关键因素之一。分辨率越高&#xff0c;所获取的图像细节越丰富&#xff0c;能够更准确地反映地物的特征和变化。因此&#xff0c;在选择卫星遥感影像时&#xff0c;需要根据实际需求和数据可获取性来选择合适的分辨率。 一、分辨…

Python向带有SSL/TSL认证服务器发送网络请求小实践(附并发http请求实现asyncio+aiohttp)

1. 写在前面 最近工作中遇到这样的一个场景&#xff1a;给客户发送文件的时候&#xff0c;为保证整个过程中&#xff0c;文件不会被篡改&#xff0c;需要在发送文件之间&#xff0c; 对发送的文件进行签名&#xff0c; 而整个签名系统是另外一个团队做的&#xff0c; 提供了一…

AI大语言模型GPT —— R 生态环境领域数据统计分析

自2022年GPT&#xff08;Generative Pre-trained Transformer&#xff09;大语言模型的发布以来&#xff0c;它以其卓越的自然语言处理能力和广泛的应用潜力&#xff0c;在学术界和工业界掀起了一场革命。在短短一年多的时间里&#xff0c;GPT已经在多个领域展现出其独特的价值…

数据挖掘入门项目二手交易车价格预测之建模调参

文章目录 目标步骤1. 调整数据类型&#xff0c;减少数据在内存中占用的空间2. 使用线性回归来简单建模3. 五折交叉验证4. 模拟真实业务情况5. 绘制学习率曲线与验证曲线6. 嵌入式特征选择6. 非线性模型7. 模型调参&#xff08;1&#xff09; 贪心调参&#xff08;2&#xff09;…

C++从入门到精通——初步认识面向对象及类的引入

初步认识面向对象及类的引入 前言一、面向过程和面向对象初步认识C语言C 二、类的引入C的类名代表什么示例 C与C语言的struct的比较成员函数访问权限继承默认构造函数默认成员初始化结构体大小 总结 前言 面向过程注重任务的流程和控制&#xff0c;适合简单任务和流程固定的场…

电商技术揭秘八:搜索引擎中的SEO内部链接建设与外部推广策略

文章目录 引言一、 内部链接结构优化1.1 清晰的导航链接1. 简洁明了的菜单项2. 逻辑性的布局3. 避免深层次的目录结构4. 使用文本链接5. 突出当前位置6. 移动设备兼容性 1.2 面包屑导航1. 显示当前页面位置2. 可点击的链接3. 简洁性4. 适当的分隔符5. 响应式设计6. 避免重复主页…

c# wpf XmlDataProvider 简单试验

1.概要 2.代码 <Window x:Class"WpfApp2.Window12"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend…

Debian12 使用 nginx 与 php8.2 使用 Nextcloud

最近将小服务器升级了下系统&#xff0c;使用了 debian12 的版本&#xff0c;正好试试 nginx 和 php-fpm 这种方式运行 Nextcloud 这个私有云的配置。 一、基本系统及应用安装 系统&#xff1a;debian12 x86_64 位版本最小安装&#xff0c;安装后可根据自己需求安装一些工具&…

《图解Vue3.0》- 调试

如何对vue3项目进行调试 调试是开发过程中必备的一项技能&#xff0c;掌握了这项技能&#xff0c;可以很好的定义bug所在。一般在开发vue3项目时&#xff0c;有三种方式。 代码中添加debugger;使用浏览器调试&#xff1a;sourcemap需启用vs code 调试&#xff1a;先开启node服…

python标准数据类型--集合常用方法

在Python中&#xff0c;集合&#xff08;Set&#xff09;是一种无序且不重复的数据结构&#xff0c;它是由一个无序的、不重复的元素组成的。Python中的集合与数学中的集合概念相似&#xff0c;并且支持一系列常用的方法。本篇博客将深入介绍Python集合的常用方法&#xff0c;帮…