由于Unity与Android交互开发步骤繁琐,且容易出错,本篇文章以具体项目为样例,以便形象化展示。
用到的Unity版本为2021.3.19,AS版本为2022.3,Android真机Redmi K30 Pro
示例项目的创建
创建Unity项目
设置Android平台相关参数(基于Unity的Android开发(主要参数的设置)-CSDN博客)。
注意1.Identification设置
包名必须是<com.公司名.产品名>的形式,且与AS项目同步;
最低SDK级别需要与AS项目同步,此处选择Android 5.1(22);目标级别建议选最大。
注意2.密钥库的创建与设置
1.在Publishing Settings下,点击Keystore Manager...
2.在Keystore Manager窗口中点击左上角Keystore...-->Create New-->Anywhere...默认在项目根目录创建密钥库;
3.设置密钥库密码、创建密钥并设置密码及有效期。点击Add Key创建。其他密钥信息设置此处不再介绍,可跳过;
4.创建场景CallAndroid,调整为目标设备分辨率。
创建AS项目
新项目的创建
1.打开AS,创建新项目。选择Phone and Tablet,右侧选择Empty Activity(2022.3及以上版本的Empty Activity样例无法选择JAVA作为开发语言,可改为EmptyViews Activity)样例,点击Next;
2.1.Package name及Minimum SDK版本需与Unity一致。点击Finish;
2.2.若无对应SDK选项,打开AS窗口-->File-->Settings,搜索"SDK"
勾选所需SDK,等待下载完毕即可;
3.等待项目加载完毕,方可进行后续操作;
注意:Sync
当AS项目做出修改时,编译器上方会提示同步,此时点击Sync Now即可(全文通用)。
交互前的准备
1.删除Android页签-->app-->java下的两个test项目及app-->res下的所有资源文件(目前用不到)
2.由于接下来需要将AS项目以拓展包的形式导入Unity,因此需要改变AS项目的性质(即从应用改为拓展包):
切换为Project页签,打开项目-->app-->build.gradle文件,将plugins下的id 'com.android.application' 改为id 'com.android.library',并将defaultConfig下的applicationId整行删除;
打开app-->src-->main-->AndroidManifest.xml配置文件,删除选中的代码:
3.打开使用的Unity对应版本的安装目录下Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono(il2cpp)\Release\Classes文件夹
将classes.jar文件复制到AS项目的app\libs文件夹下;
注意:下划线处的路径选择,取决于Unity项目勾选的打包模式(Player Settings-->Other Settings-->Configuration-->scriptingBackend);
回到AS工程目录,右键点击app-->libs-->classes.jar-->Add As Library...
选择当前项目,点击OK;
4.打开使用的Unity对应版本的安装目录下Editor\Data\PlaybackEngines\AndroidPlayer\Source\com文件夹,将unity3d文件夹复制到AS项目app\src\main\java\com文件夹下;
5.打开MainActivity.java脚本,修改继承关系为UnityPlayerActivity,并移除这行代码setContentView(R.layout.activity_main)(此为layout的设置,由于删除了资源,此处不需要)。并调整引用信息;
6.回到app-->src-->main-->AndroidManifest.xml配置文件,在</intent-filter>标签后添加<meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
Unity与Android的交互
在前述项目的基础上继续操作。
Unity调用Android
1.在MainActivity.java脚本中添加一些成员变量和函数以供Unity测试调用;
2.点击Build-->Make Module等待编译项目完成
3.1.打开AS项目app\build\outputs\aar文件夹,见app-debug.aar文件;打开app\src\main文件夹,见AndroidManifest.xml文件;
3.2将上述两个文件复制至Unity项目Assets-->Plugins-->Android文件夹下;
3.3使用解压工具打开Unity项目中的app-debug.aar文件
删除根目录classes.jar-->com-->unity3d文件夹、删除libs下的classes.jar文件,保存;
4.在Unity项目中创建脚本UnityCallAndroid.cs:
在Start()中尝试调用前面的JAVA函数,并在UI Text中显示。回到Unity中创建这个Text,设置合适的参数;挂载脚本,引用Text UI物体;
5.发布项目,可选择打包成apk文件或直接发布到USB调试设备中
正确运行。
Android调用Unity
前提条件:被调用的函数必须写在继承MonoBehaviour的脚本中,并且此脚本挂载在场景中激活的游戏物体上;
调用语法:UnityPlayer.UnitySendMessage("对象名","函数名","参数");
1.新建脚本AndroidCallUnity.cs,添加待调用的测试函数:
该函数将传入的字符串显示在UI Text中;将脚本挂载在物体“Canvas”上;
2.打开AS项目,直接在onCreate函数中调用测试函数,使其在一开始执行,保险起见将程序集路径写全:
这里我们传入的参数是 "AndroidCallUnity";
3.重新执行<Unity调用Android>板块中的2,3,5步,替换掉重名文件,并发布:
成功运行。
Unity与Android相互嵌入
在Android原生概念中,我们对应用的操作即是对安卓四大组件(Activity,Service,Broadcast Receiver,Content Provider)的操作。此处我们以Activity为例,所谓Unity与Android相互嵌入,指的就是两者相互启动对方的Activity。
Unity中嵌入Android
1.打开之前的AS项目,右键点击MainActivity的父级-->New-->Activity-->Empty Views Activity创建新的Activity以供Unity端启动(此处方便起见直接在之前的项目中操作,建议新建项目并按前述步骤重新初始化)。
修改名称,点击Finish。此Activity相当于我们期望嵌入Unity中的Android界面。
2.打开脚本,另其继承自Activity(原AppCompatActivity包含标题栏,此处不需要);
鼠标移至紫色字体“activity_android”上,按下快捷键CTRL+鼠标左键进入当前Activity的UI编辑界面;
添加一些UI元素,进行对齐;
3.在MainActivity脚本中添加启动此Activity的函数,供Unity调用:
4.重新执行<Unity调用Android>板块中的2,3步骤;
5.回到Unity中,在UnityCallAndroid脚本的Start()在添加调用语句(最后一行):
在场景中添加UI Button,当点击按钮时,调用启动新Activity的方法;
6.由于项目中用到了Android原生UI组件,因此建议发布为AS工程,到AS中进行打包。勾选Export Project,点击Export;
7.用AS打开发布的项目。待加载完成后,
7.1.打开Project页签-->项目名-->gradle.properties文件,删除"android.enableR8=false";
7.2.打开Project页签-->项目名-->unityLibrary-->build.gradle文件,在dependencies中添加依赖:implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
应与原AS项目Project页签-->项目名-->app-->build.gradle文件中的dependencies相同;
并在7.1中的gradle.properties文件里添加android.useAndroidX=true
7.3.将roject页签-->项目名-->unityLibrary-->src->main-->AndroidManifest.xml打开,删除
<category android:name="android.intent.category.LAUNCHER" />
7.4.打开File-->Settings-->Build, Execution, Deployment-->Build Tools-->Gradle-->Gradle JDK
确保JDK版本与Unity使用的一致。此处直接选择了Unity安装目录下的JDK,但具体情况需具体分析解决;
8.点击Build-->Build Bundle/APKs-->Build APKs等待编译完成:
9.1.点击Build-->Generate Signed Bundle/APK...生成apk文件;
9.2.选择APK点击Next
选择之前创建的Key store,填入密码;选择密钥,填入密码,点击Next
选择release发布版(调试则选debug),等待编译完成;
9.3.打开项目目录launcher\release,见launcher-release.apk,安装到目标设备:
点击按钮,正确运行。
Android中嵌入Unity
1.新建Unity项目,切换至Android平台。添加场景UnityInAndroid,创建脚本CubeRotate.cs,挂载在场景中新建的Cube上:
该脚本保持Cube在场景中不断旋转。此场景作为测试Activity被Android调用;
2.导出项目为AS工程,由于是在Android中嵌入Unity,因此Unity无需进行参数设置;
3.新建AS项目,步骤同<创建AS项目-新项目的创建>板块,不过由于上述原因,此处无需限制包名和SDK版本;
4.1.打开Unity导出项目,将unityLibrary文件夹复制到新建的AS项目中;
4.2.将Unity导出项目的launcher\src\main\res下所有文件,复制到新建的AS项目unityLibrary\src\main\res文件夹下,跳过重名文件;
5.1.打开新建的AS项目Project页签-->项目名-->settings.gradle文件,在尾行添加include ':unityLibrary'
5.2.打开Project页签-->项目名-->app-->build.gradle文件,在dependencies中添加implementation project(':unityLibrary')
5.3.打开Project页签-->项目名-->gradle.properties文件,添加unityStreamingAssets=.unity3d, google-services-desktop.json, google-services.json, GoogleService-Info.plist
5.4.打开Project页签-->项目名-->unityLibrary-->build.gradle文件,在android标签中添加namespace 'com.unity3d.player'
5.5.打开打开Project页签-->项目名-->unityLibrary-->src-->main-->AndroidManifest.xml文件,删除选中内容;
6.1.为MainActivity添加UI,此处添加一个Button(添加方法见<Unity中嵌入Android>板块步骤2),将button id设置为btnUnity;
6.2.在MainActivity中为该button添加事件,通过点击进入Unity的Activity;
7.执行<Unity中嵌入Android>板块步骤8,9,运行软件:
正确运行。