关于 Unity 不同方式的导出与详细使用的说明(基于 Android 平台)
导出方式(编译器选择)
已有方式如下:
1.Mono
- Mono 是一个由 Xamarin 公司所主持的自由开放源码项目。
Mono 的目标是在尽可能多的平台上使.net 标准的东西能正常运行的一套工具,核心在于”跨平台地让.net 代码能运行起来”。
Mono 组成组件:C# 编译器,CLI 虚拟机,以及核心类别程序库。
Mono 的编译器负责生成符合公共语言规范的映射代码,即公共中间语言(Common Intermediate Language,CIL),我的理解就是工厂方法实现不同解析。
- Mono 是一个由 Xamarin 公司所主持的自由开放源码项目。
2.IL2CPP
IL 的全称是 Intermediate Language,IL 是与 CPU 无关的机器语言,能访问和操作对象类型,并提供了指令来创建和初始化对象、调用对象上的虚方法以及直接操作数组元素。甚至提供了抛出和捕捉异常的指令来实现错误处理。可将 IL 视为一种面向对象的及其语言。很多时候还会看到 CIL(特指在.Net 平台下的 IL 标准)。翻译过来就是中间语言。
它是一种属于通用语言架构和.NET 框架的低阶的人类可读的编程语言。
CIL 类似一个面向对象的汇编语言,并且它是完全基于堆栈的,它运行在虚拟机上(.Net Framework, Mono VM)的语言。IL2CPP 分为两个独立的部分:
- AOT(静态编译)编译器:把 IL 中间语言转换成 CPP 文件
- 运行时库:例如垃圾回收、线程/文件获取(独立于平台,与平台无关)、内部调用直接修改托管数据结构的原生代码的服务与抽象
Unity 跨平台原理
Mono 运行时编译器支持将 IL 代码转为对应平台原生码。
IL 可以在任何支持 CLI(通用语言环境结构)中运行,IL 的运行是依托于 Mono 运行时。
总结
IL2CPP 比较适合开发和发布项目 ,但是为了提高版本迭代速度,可以在开发期间切换到 Mono 模式(构建应用快)。如图:
在选择编译方式后,可选择编译平台架构(armv7、arm64)以及 C#编译 API 库版本(.net)
推荐开发工具版本
- Android Studio Bumblebee (2021.3.1) or later
- Unity version 2021.3.4a18 or later
- Visual Studio Code 1.75.1 (Code)
导出步骤
基础配置
- 预配置
- 填充 unity file 菜单 project settings 中 company name、package name 名称
- 设置导出路径,勾选导出文件
- 复制 Unitylibrary 目录至 Android Studio 工程
- 更改
build.gradle
文件等
- 更改
- 启动 Android 程序,跳转至选图后界面
- 启动 unity,预览程序
- 导出
- export(File->Build Settings) 页面配置,如图:
- export(File->Build Settings) 页面配置,如图:
- 在 player settings 中设置如下项目,如图:(选中 Android 项目)
- 在 player settings 中设置如下项目,如图:(选中 Android 项目)
- 设置发布配置,如图:
- 设置发布配置,如图:
- 设置启动页面
- 设置启动页面
- 最终,在 Build Settings 页面中点击 export 导出,如图:
- 最终,在 Build Settings 页面中点击 export 导出,如图:
- 导出前性能优化
- 物理模块优化
- 1.如果项目使用 Unity 2017 以上版本,且实际没有使用物理模块,可以将 Project Settings 中 Physics 的 Auto Simulation 和 Auto Sync Transforms 选项关闭(如图)
- 1.如果项目使用 Unity 2017 以上版本,且实际没有使用物理模块,可以将 Project Settings 中 Physics 的 Auto Simulation 和 Auto Sync Transforms 选项关闭(如图)
导出性能分析
在 Android Studio Profiler 性能分析中,Unity 占用内存的判断
- 如图,native 内存即为 Unity 占用内存
Android Studio 引入 Unity 导出库配置(以官方案例为参考)
在 Unity 编辑器中打开 UnityProject
进入构建设置窗口(菜单/文件/构建设置)
选择并切换到 Android 平台
进入播放器设置窗口(点击构建设置左下角的播放器设置按钮,或者使用编辑/项目设置菜单,选择左边的播放器选项卡)
在”其他设置”—)配置”中选择目标架构
- 返回”构建设置”窗口 -选择”导出项目”选项
![img](unityexport-to-android-md/exportProject.png” width=’400px’>
导出 UnityProject 到 androidBuild 文件夹,文件夹结构如下所示
- 返回”构建设置”窗口 -选择”导出项目”选项
3.添加 Unity 库模块到 NativeAndroidApp**
在 Android Studio 中将导出的 androidBuild/unityLibrary 模块添加到 NativeAndroidApp Gradle 项目中:
在 Android Studio 中打开 NativeAndroidApp
打开设置.gradle 文件
在主 app 模块之后添加一个指向 unityLibrary 模块的新项目
1 | include ':unityLibrary' |
- 在”dependencyresoltionmanagement {repositories{block”中添加如下内容
1 | flatDir { |
![img](/2023/02/22/unityexport-to-android-md/settingsGradle.png)
开放构建.gradle(模块:NativeAndroidApp.app)文件
在 dependencies{block 中添加以下内容
1 | implementation project(':unityLibrary') |
![img](/2023/02/22/unityexport-to-android-md/buildGradleApp.png)
- 在同一个文件中,看看 android{defaultConfig{ndk{块,并确保 abiFilters 匹配你在 Unity 编辑器中选择的架构,然后再导出项目。过滤器必须与 Unity 编辑器中的架构完全匹配。如果 Unity 只导出 ARMv7 架构,但过滤器包含 ARM64 -v8a,应用程序将在 ARM64 设备上崩溃。在android 官方文档中检查有效的 abiFilters 值。
- 复制 gradle 的内容。属性文件从导出的 Unity 项目根文件夹到 gradle。属性文件在本机应用程序根文件夹中。注意:如果你更新 Unity 项目并再次重新导出它,请确保 gradle 的内容。导出项目中的属性文件没有更改。如果有,重复这一步。
- 点击 Sync Now 进行项目同步,因为 Gradle 文件已经被修改了
- 点击 Sync Now 进行项目同步,因为 Gradle 文件已经被修改了
- 复制 gradle 的内容。属性文件从导出的 Unity 项目根文件夹到 gradle。属性文件在本机应用程序根文件夹中。注意:如果你更新 Unity 项目并再次重新导出它,请确保 gradle 的内容。导出项目中的属性文件没有更改。如果有,重复这一步。
- 如果一切成功,你应该看到 unityLibrary 模块添加到 Android 视图
项目准备就绪
一切就绪,可以构建、运行和调试:
![img](/2023/02/22/unityexport-to-android-md/buildOnDevice.png)
如果一切成功,在这一点上,你应该能够运行 NativeAndroidApp:
Main Activity | Unity Activity |
---|---|
![]() |
![]() |
Main Activity | Unity 被加载并运行在一个单独的 Activity 中。中间的浅灰色按钮是从 MainUnityActivity 中添加的,在 NativeAndroidApp 中实现 |
注意
- Unity 运行在另一个进程 android:process=”:Unity” (AndroidManifest.xml 在应用模块)
安装完成后,设备上会增加两个图标。要只留下主活动的图标,删除… from AndroidManifest.xml 在 unityLibrary - (可选)我们找到了一些 Android 7。*设备将活动的 frontOfTask 设置为错误状态,导致当完成/退出 Unity 活动时,整个任务将进入后台,而不是带回主活动。下一个解决方案保持预期的行为:添加到 MainUnityActivity.java 从 NativeAndroidApp
1
2
3
4@Override
public void onUnityPlayerQuitted() {
showMainActivity(""); finish();
}