Unity 项目迁移鸿蒙(一):环境准备与工程结构
将已有 Unity 项目迁移到 HarmonyOS的第一步,是先让项目能在团结引擎中正常运行并成功导出 OpenHarmony 工程。本文从环境安装开始,依次梳理平台切换、基础代码适配、导出工程结构,以及包名、应用名、图标和模拟器等常用配置。
在将现有的 Unity 项目迁移到基于 OpenHarmony(鸿蒙)架构的团结引擎时,由于底层操作系统从 Android(AOSP)完全切换到了鸿蒙架构,很多历史遗留的 Android 逻辑、原生库以及打包配置都会失效并导致报错。
本系列将按照实际迁移顺序,介绍环境搭建、报错排查、SDK 适配和自动化构建等内容。
本篇先介绍环境准备与团结引擎的 ArkTS 工程结构。
- 下载并安装团结 Hub。
- 通过团结 Hub 安装团结引擎,并勾选 OpenHarmony Build Support 模块。
鸿蒙的原生 IDE 是华为自研的 DevEco Studio,它是构建、签名、调试鸿蒙应用的核心,类似于 Android 开发中的 Android Studio。
- 前往华为开发者联盟下载 DevEco Studio。
- 首次打开团结引擎导出的工程时,如果 IDE 提示选择构建 SDK 版本,可选择自动同步,以使用与团结引擎匹配的 SDK。
提审分支通常会裁剪玩法、数据上报等代码,不利于完整验证平台兼容性。建议从功能完整且相对稳定的正式版本分支开始迁移,再将适配结果合并到目标发布分支。
直接使用 OpenHarmony 平台打开项目,一路选择允许切换平台。
- 插件适配:部分插件无法直接在 Unity 与团结引擎之间复用,例如 URP。如果项目对于插件的代码有修改,则需要先备份修改,再移除
Packages目录中的原插件,安装兼容版本后解决报错并同步原有修改 - 平台选择:如果需要在模拟器进行测试,需要勾选 x86_64 平台(正式发行一定避免勾选)
- 网络配置:与升级至 Unity 2022 版本一致,如果项目需要访问 HTTP 资源,在
Project Settings > Player > Other Settings中将Allow downloads over HTTP设置为Always allowed。
旧项目通常充满了 Android 或 iOS 的宏,鸿蒙系统需要添加专门的宏。团结引擎为 OpenHarmony 提供了专门的宏定义:UNITY_OPENHARMONY。比如:
#if UNITY_OPENHARMONY
#elif UNITY_ANDROID
#endif
修复编辑器中可见的编译错误,并不代表平台适配已经完成。部分问题只会在导出工程、构建 HAP 或真机运行时出现,需要结合后续日志逐项排查。
团结引擎的默认字体,与Unity的默认字体不同,如果原有代码中有设置默认字体的逻辑,就会报错。需要根据团结引擎,选择另外的默认字体。
if (m_font) return;
#if UNITY_OPENHARMONY
m_font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
#else
m_font = Resources.GetBuiltinResource<Font>("Arial.ttf");
#endif
处理完编辑器和导出阶段的错误后,OpenHarmony 工程成功导出。下面开始介绍 OpenHarmony 工程的结构。
对于安卓开发者来说,OpenHarmony 工程结构与 Android Studio 有很多相似之处:
Project
│
├── AppScope
│ └── app.json5
│ └── resources
│
├── entry (launcher)
│ ├── src
│ │ └── main
│ │ ├── ets (src/main/java)
│ │ ├── resources
│ │ │ ├── base
│ │ │ │ ├── media (drawable)
│ │ │ │ ├── element (values)
│ │ │ │ └── profile
│ │ └── module.json5 (AndroidManifest.xml)
│ │
│ ├── oh-package.json5 (build.gradle)
│ └── build
│
├── tuanjieLib
│ ├── libs
│ ├── src
│ │ └── main
│ │ ├── ets (src/main/java)
│ │ │ └── gen
│ │ │ └── TuanjieJSScriptRegister.ets
│ │ ├── resources
│ │ │ └── rawfile (src/main/assets)
│ │ │ └── Data
│ │ │ ├── Managed
│ │ │ └── StreamingAssets
│ │ └── module.json5 (AndroidManifest.xml)
│ └── oh-package.json5 (build.gradle)
│
├── hvigor
├── build-profile.json5 (settings.gradle)
├── hvigorfile.ts (settings.gradle)
└── oh-package.json5
这里整理了一个常见文件的速查表:
下面是 OpenHarmony 工程中需要额外关注的目录:
与 Unity 2022.x 相比,团结引擎在构建 IL2CPP 的过程中,OpenHarmony 工程的构建方式与 Android Studio 工程有很大不同。
从Unity 2021.x 版本开始,IL2CPP 的构建从原先在 Unity 中进行,改为了在 Android Studio 中进行。Unity 导出 Android Studio 工程后,会将代码存储在 Il2CppOutputProject 目录下,在构建 APK 时再由 Android Studio 进行 IL2CPP 的构建。
而团结引擎导出 OpenHarmony 工程时,IL2CPP 的构建则是自动进行的。导出时,代码存储在导出目录同级的 Il2CppBackup 目录后,由团结引擎自动进行 IL2CPP 的构建。也就是说,团结引擎执行完导出工程步骤后,IL2CPP 的构建就已经完成了,DevEco Studio 只需要进行打包即可。
因为导出代码的路径是导出路径同级的 Il2CppBackup 目录。所以在生产环境中,应该注意不同项目导出路径的分割,避免同步进行时出现冲突。
AppScope/app.json5 是应用级的配置,但团结引擎导出工程的应用名和图标还会受到 entry 模块资源的影响,所以不能只修改这一处。
根据 IDE 提示可以确定:如果要修改应用名,去修改 string: "app_name";图标则是 media/app_icon.png。但修改后并不会生效,因为实际上获取的是其他路径下的图标。
这里只有启动窗口图标的修改会生效:media/start_icon.png,这个图片是应用运行起来后首先显示的图片。
应用名和 icon 则需要转到 entry 这个模块下进行修改。打开 entry/src/main/module.json5 可以查看相关信息,IDE 会提示应用名(label)和图标(icon)的修改位置。
应用名需要修改以下三个文件:
entry/src/main/resources/base/element/string.jsonentry/src/main/resources/zh_CN/element/string.jsonentry/src/main/resources/en_US/element/string.json
对应的字段是 EntryAbility_label。
图标对应的目录是 entry/src/main/resources/base/media。默认图标为 icon.png。
如果发布渠道要求使用自适应图标,可将配置改为 layeredIcon,前景和背景资源分别使用 ic_launcher_foreground.png 与 ic_launcher_background.png。
除此之外,这个目录下还有 app_splash.png,它的显示时机在 start_icon 之后、游戏启动之前。显示时长不确定。所以我推荐使用暗色纯色图片,防止用户被闪到。
包名推荐在较早时间确定。因为在配置打包签名后,会提升修改包名的难度。这时候可以按照下面步骤执行:
打开 File > Project Structure > Signing Configs,修改包名,然后点击 Apply 应用,即可同步签名中的包名。
IDE 中的修改不一定会写入工程。可以检查项目根目录的 build-profile.json5,手动将 app.products.signingConfig 字段指向新增的签名配置。
默认模拟器的存储空间可能不足,安装较大的 HAP 时容易失败。创建模拟器时建议根据项目包体大小适当提高存储容量,并为后续多次安装预留空间。