Unity 项目迁移鸿蒙(二):打包与调试
完成环境配置并成功导出 OpenHarmony 工程后,下一步是让游戏在模拟器或真机上稳定运行。本文主要围绕 DevEco Studio 调试展开,介绍设备文件与 HiLog 的查看方法、平台代码兼容、远程真机连接、Jenkins 构建注意事项,以及 Unity 日志转发到 HarmonyOS 原生层的实现。
本篇目标
经过上一篇的基础适配,项目已经可以导出 HAP,并在模拟器或真机中启动。不过,一些平台相关逻辑只会在运行阶段暴露问题,需要结合 DevEco Studio 日志与游戏内日志继续排查。
模拟器适合验证安装、启动和基础流程。因为目前在渲染层面上,鸿蒙模拟器没有对游戏有很好的支持。游戏的渲染效果、性能、设备能力及第三方 SDK 行为应以真机上的测试结果为准。
使用 DevEco Studio 定位问题
应用文件查看
Android 调试中可以通过设备文件管理器查看应用内的文件,HarmonyOS 应用不能,需要借助 DevEco Studio 的设备文件浏览功能访问和修改沙箱内的文件。
依次打开:View > Tool Windows > Device File Explorer。
然后在文件树中导航到:
/data/app/el2/100/base/<你的包名>/haps/entry/files/ |
应用文件替换
Device File Explorer 允许拉取文件,无法完成文件的推送。如果要传入某个文件,需要使用 HDC 命令。
以应用沙箱下的 res 目录为例:
hdc file send -b your.package.name your_file_path "./data/storage/el2/base/haps/entry/files/res" |
DevEco Studio 日志查看
如果日志窗口中只有少量输出,先检查当前是否停留在 FaultLog。它主要用于查看故障信息,并不等同于 Android Studio 中的完整 Logcat。
在日志面板中切换到 HiLog,即可查看更完整的运行日志。排查时可优先按包名、进程或自定义日志域过滤,减少系统日志干扰。
快速拷贝代码
直接重新导出会覆盖手动修改过的 OpenHarmony 工程。在业务环境的一般做法是:保留一份已经完成适配的原生工程,每次导出后只同步代码、资源和原生库。
下面的批处理脚本会同步 Managed 和 libs 两个目录,便于在接入调试时快速实现代码逻辑的更新。
执行前应将 {导出目录} 与 {兼容目录} 替换为真实路径:
@echo off |
处理平台相关代码
除了上一篇提到的 #if UNITY_ANDROID 条件编译,项目中还可能存在运行时的平台判断,自定义的平台枚举、路径规则和 SDK 处理逻辑。这类逻辑不一定触发编译错误,通常需要结合运行表现和日志定位。
RuntimePlatform
RuntimePlatform 是 Unity 用于标识当前运行平台的枚举。迁移时应全局搜索它,检查原有 Android 分支是否需要补充 OpenHarmony 处理逻辑。
除此之外,还会有以下区分平台的内容:
UNITY_ANDROID、UNITY_IOS等平台宏;RuntimePlatform和项目自定义平台枚举;Application.platform、Application.persistentDataPath等平台相关 API;- Java、JNI、Android Activity 或 Intent 等原生调用。
远程调试真机
当测试设备不方便通过 USB 连接线进行连结时,可以使用 HDC 的无线连接功能进行安装和调试。开发机与设备应处于可互通的同一内网中。
打开无线调试
在设备的 设置 > 系统 > 开发者选项 中打开无线调试,并记录设备的 IP 地址和端口号。
在 DevEco Studio 终端中执行:
hdc tconn <设备 IP>:<端口号> |
可通过 hdc list targets 命令确认设备是否已经连接成功。
配置真机调试签名
在 IDE 顶部的设备列表中选择刚刚连接的设备,然后点击编译运行项目,即可进行远程安装。
首次安装时如果出现签名错误,可根据 DevEco Studio 的提示创建调试用的签名,这一步需要登录华为开发者账号。
Jenkins 自动化构建
Jenkins 与 C# 构建入口
团结引擎仍可通过编辑器命令行参数调用 C# 构建方法,整体流程与 Unity 类似。
需要注意的是,团结引擎产品版本与编辑器版本采用不同的编号规则。例如,团结引擎 1.9.3 对应的编辑器版本应为 2022.3.62t11。Jenkins 任务应以实际安装的编辑器路径和版本为准,不要直接使用产品版本号拼接路径。
BuildPlayer 参数差异
Unity 导出 Android Studio 或 Xcode 工程时,常会使用 BuildOptions.AcceptExternalModificationsToPlayer 这个枚举。
团结引擎导出 DevEco Studio 工程时不需要指定该参数。迁移现有构建脚本时,应将它从 OpenHarmony 分支中移除,避免沿用 Android/iOS 的导出配置。
将 Unity 日志转发到 HiLog
如果 Unity 日志在 HiLog 中无法打印,或者为了集中管理日志,可以在团结引擎中注册 Application.logMessageReceived 消息,再通过原生桥接将日志转发到 HarmonyOS 的 hilog。
这个示例也展示了团结引擎 C# 与 ArkTS 代码之间最基础的调用方式。
创建 LogBridge
在 tuanjieLib/src/main/ets 下创建 bridge 目录,并新建 LogBridge.ets:
import hilog from '@ohos.hilog'; |
%{public}s 表示日志内容可以公开显示,便于调试时查看完整文本。发布时应避免把账号、Token 等敏感信息写入日志,可以用 %{private}s 来隐藏这些信息。
注册并导出 LogBridge
首先在 tuanjieLib/build-profile.json5 的 arkOptions.runtimeOnly.sources 中加入:
"./src/main/ets/bridge/LogBridge.ets" |
这一步是避免代码在编译时被裁剪掉,确保桥接类在运行时可用。
然后在 tuanjieLib/exported.ets 中导出 LogBridge:
export { LogBridge } from './src/main/ets/bridge/LogBridge'; |
最后,在 tuanjieLib/src/main/ets/gen/TuanjieJSScriptRegister.ets 中引入注册函数,并在 RegisterJSScriptToCSharp 中完成注册:
import { RegisterLogBridge } from '../bridge/LogBridge'; |
在 C# 中转发日志
原生工程注册完成后,在 Unity C# 代码中订阅日志回调并调用桥接类:
Application.logMessageReceived += OnLogMessage; |
建议在 Awake 等初始化阶段创建并缓存 OpenHarmonyJSClass,不要在每条日志到来时重复实例化。这样既能避免桥接对象尚未完成初始化的问题,也能减少频繁创建对象带来的开销。
还需要注意两点:
- 在对象销毁或应用退出时取消
Application.logMessageReceived订阅,避免重复注册; - 桥接调用失败时不要再通过 Unity 日志记录异常,否则可能造成递归调用。



