关于 Unity 不同方式的导出与详细使用的说明(基于 Android 平台)
Published in:2023-02-22 |
Words: 1.6k | Reading time: 6min | reading:

关于 Unity 不同方式的导出与详细使用的说明(基于 Android 平台)

导出方式(编译器选择)

  • 已有方式如下:

  • 1.Mono

    • Mono 是一个由 Xamarin 公司所主持的自由开放源码项目。
      Mono 的目标是在尽可能多的平台上使.net 标准的东西能正常运行的一套工具,核心在于”跨平台地让.net 代码能运行起来”。
      Mono 组成组件:C# 编译器,CLI 虚拟机,以及核心类别程序库。
      Mono 的编译器负责生成符合公共语言规范的映射代码,即公共中间语言(Common Intermediate Language,CIL),我的理解就是工厂方法实现不同解析。
  • 2.IL2CPP

    • IL 的全称是 Intermediate Language,IL 是与 CPU 无关的机器语言,能访问和操作对象类型,并提供了指令来创建和初始化对象、调用对象上的虚方法以及直接操作数组元素。甚至提供了抛出和捕捉异常的指令来实现错误处理。可将 IL 视为一种面向对象的及其语言。很多时候还会看到 CIL(特指在.Net 平台下的 IL 标准)。翻译过来就是中间语言。
      它是一种属于通用语言架构和.NET 框架的低阶的人类可读的编程语言。
      CIL 类似一个面向对象的汇编语言,并且它是完全基于堆栈的,它运行在虚拟机上(.Net Framework, Mono VM)的语言。

      • IL2CPP 分为两个独立的部分:

        1. AOT(静态编译)编译器:把 IL 中间语言转换成 CPP 文件
        1. 运行时库:例如垃圾回收、线程/文件获取(独立于平台,与平台无关)、内部调用直接修改托管数据结构的原生代码的服务与抽象
  • 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)

导出步骤

基础配置

    1. 预配置
      1. 填充 unity file 菜单 project settings 中 company name、package name 名称
      1. 设置导出路径,勾选导出文件
      1. 复制 Unitylibrary 目录至 Android Studio 工程
      1. 更改build.gradle文件等
      1. 启动 Android 程序,跳转至选图后界面
      1. 启动 unity,预览程序
    1. 导出
      1. export(File->Build Settings) 页面配置,如图:
      1. 在 player settings 中设置如下项目,如图:(选中 Android 项目)
      1. 设置发布配置,如图:
      1. 设置启动页面
      1. 最终,在 Build Settings 页面中点击 export 导出,如图:
    1. 导出前性能优化
    • 物理模块优化
      • 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
2
include ':unityLibrary'
project(':unityLibrary').projectDir=new File('..\\UnityProject\\androidBuild\\unityLibrary')
  • 在”dependencyresoltionmanagement {repositories{block”中添加如下内容
1
2
3
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
  • 开放构建.gradle(模块:NativeAndroidApp.app)文件

  • 在 dependencies{block 中添加以下内容

1
2
implementation project(':unityLibrary')
implementation fileTree(dir: project(':unityLibrary').getProjectDir().toString() + ('\\libs'), include: ['*.jar'])
  • 在同一个文件中,看看 android{defaultConfig{ndk{块,并确保 abiFilters 匹配你在 Unity 编辑器中选择的架构,然后再导出项目。过滤器必须与 Unity 编辑器中的架构完全匹配。如果 Unity 只导出 ARMv7 架构,但过滤器包含 ARM64 -v8a,应用程序将在 ARM64 设备上崩溃。在android 官方文档中检查有效的 abiFilters 值。
    • 复制 gradle 的内容。属性文件从导出的 Unity 项目根文件夹到 gradle。属性文件在本机应用程序根文件夹中。注意:如果你更新 Unity 项目并再次重新导出它,请确保 gradle 的内容。导出项目中的属性文件没有更改。如果有,重复这一步。
      • 点击 Sync Now 进行项目同步,因为 Gradle 文件已经被修改了
  • 如果一切成功,你应该看到 unityLibrary 模块添加到 Android 视图

项目准备就绪

一切就绪,可以构建、运行和调试:

如果一切成功,在这一点上,你应该能够运行 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();
    }
Prev:
Unity 中绕某个物体旋转方法
Next:
关于 Unity 中触摸屏幕坐标与物体世界坐标的判定方法(以矩形为例)