22.总结
22.1 核心要点速览
原生路线和 Unity 路线各干什么
- 原生 Android:Java/Kotlin + Android Studio + SDK,从零写 App、自己管 Activity、权限、系统 API。
- Unity 跨平台:玩法、资源、渲染在编辑器里做完,导出 APK/AAB 给手机跑;不必把原生栈学到能独立写应用,缺什么补什么。
- 行业里 纯应用岗 很多还是 Java 系;游戏客户端 这边跨平台引擎更常见,单独为手机再写一套原生客户端的情况反而少。
用 Unity 做安卓时要补什么
先能发版、能联调(小团队/原型):
- Unity 里 打 APK、真机装包跑通。
- 需要时 Export 到 Android Studio 再走 Gradle。
- 调试:设备连接、日志、Profiler / 断点(见后文「调试」块)。
要上渠道、接原生 SDK(商业项目):
- 能读懂 Java/Kotlin 文档和报错。
- Unity ↔ Android:AAR/JAR、JNI、Activity 生命周期等,用到再深啃。
- 第三方 SDK:统计、支付、广告等接入与混淆。
为何「发布/签名/SDK」常排在课表后面
- C#、玩法、UI、存档、网络 多半和平台无关;换手机只是换输入(例如 点击 代替 鼠标左键,逻辑还是同一套)。
- 包名、签名、Gradle、清单、渠道参数 往往临近 上线/接渠道 才集中出现;没交付压力时,先把游戏内容做稳更划算。
路线怎么选
- 只出包、不接复杂原生:按向导把 Player Settings 填对,Unity 直出即可,不要求 会写原生 Android UI。
- 要插件交互、接只给 Android SDK 的渠道:再系统补 构建链 + 原生侧 知识,后面课程会按专题讲。
Unity 2019+:Hub 里要装什么
在 Unity Hub 给当前编辑器勾 Android Build Support,并带上 Android SDK、NDK Tools、OpenJDK。装全后才能在 Build Settings 里切换到 Android 平台。系列里写的是:目标系统可覆盖 **Android 5.1+**,具体机型下限在 Minimum API Level 里单独定。
Player Settings 里每次打包前建议核对:
| 项 | 作用 |
|---|---|
| 公司名 / 产品名 / 版本 / 图标 | 商店展示、桌面显示名 |
| Package Name | 应用 ID,com.公司.产品 形式,别长期用默认模板 |
| Minimum API Level | 能装到的最低系统版本;过低会装不上,过高会少覆盖机型 |
构建与验证:
- 场景加入 Scenes In Build,再 Build 或 Build And Run。工程路径 和 输出路径 尽量纯英文(例如避开
...\桌面\我的游戏\这类路径,CI 和 Gradle 脚本里少踩编码坑)。 - 真机 USB 安装,或模拟器拖 APK 做冒烟。
Unity 2018 及以下:手动工具链与 External Tools
老版本不会把 JDK/SDK/NDK 全部「一键配齐」,工程量大一截:
| 项 | 要点 |
|---|---|
| Android 构建支持 | 用 Unity 安装器提供的模块下载,安装时关闭 Unity,路径常落在编辑器安装目录旁 |
| JDK | Java 8,需自行安装并配环境变量 |
| NDK | IL2CPP 出包时必选;纯 Mono 可不装。版本绑定:Unity 2018 用 r16b,Unity 2017 用 r13d(按原文) |
| Android SDK | 建议装 Android Studio,通过 SDK Manager 拉 SDK,再把路径指回 Unity |
环境变量(老流程常见): JAVA_HOME 指向 JDK 根目录;Path 追加 %JAVA_HOME%\bin 等;CLASSPATH 配 dt.jar、tools.jar 等(按教材式写法)。
External Tools 对齐后,Player Settings 里公司名、版本、Package Name、Minimum API Level 等与 2019+ 填法一致。
验证方式与新版相同:真机或模拟器装包。
Build Settings:纹理、导出形态、开发包
- Texture Compression:可跟 Player Settings 或单独指定 ETC2 / ETC / ASTC 等。Android 上 ETC2 常用且带透明;GPU 太老啃不动 ETC2 时,可退 ETC,或在 ETC2 fallback 里指定 RGBA 的兜底:32-bit / 16-bit / 半分辨率——例如老机走 16-bit 省带宽,画质差一截,是显式权衡。
- Export Project:不直接出 APK,而是导出 Gradle 工程 给 Android Studio。
- Symlink Sources:只有勾了 Export 才有;Unity 与导出目录是否 共用 Java/Kotlin 源。适合:你在 AS 里改原生,又经常从 Unity 再导一版,不想每次拷文件。
- Build App Bundle:开 → 偏 AAB(上架 Play 常用);关 → APK。
- Create symbols.zip:Public 体积小;Debugging 信息全,配合后面 Stacktrace Utility 解 native 崩溃。发版留档建议和 版本号 对齐保存。
- Development Build / Profiler / Script Debugging / Deep Profiling:调试用;Deep Profiling 开销大,别当常驻性能测试。Wait For Managed Debugger 和真机断点配合用。
- Compression Method:LZ4 / LZ4HC 偏 启动加载;LZ4HC 构建更慢、包内数据可能更省。
- 文末 Max Texture Size 与 Force Fast Compressor 一类:主要 省导入和切平台时间,和运行时画质不是一回事。
Player Settings:分辨率、方向、呈现(Android 常用项)
- 图标:Adaptive / Round / Legacy 对应不同系统版本,上架截图别用错层。
- 全屏 / 窗口 / 刘海区外绘制 / Frame Pacing:管 导航栏、刘海、帧时间分布,和「包不包得住 60」不是一回事,别和 Quality 里画质混在一块调。
- Resolution Scaling(Fixed DPI):和 Quality 里的 Resolution Scaling Fixed DPI Factor 联动,公式 **Min(Target DPI × Factor / Screen DPI, 1)**,用来在高分屏上 主动降渲染分辨率 换帧率。
- Blit Type:Always 多一次离屏,兼容性好;Never 少一次拷贝,部分机型会花屏或警告,Auto 先尝试省 Blit。
- Orientation:横竖屏、是否允许 Auto Rotation,和
Screen.orientation脚本别打架。 - Splash:启动图、Unity Logo 顺序、Personal 版能否关 Splash 以许可证为准。
Other Settings:渲染与图形 API
- Color Space:Linear 在 Android 上要 GLES 3.0 + Android 4.3+ 一类条件;机型不满足时 不会默默退回 Gamma,项目可能直接跑不起来,上线前用目标机实测。
- Auto Graphics API:默认 先试 Vulkan,不行再 GLES 3.x;自己排序时小心 最低 GLES 版本 写进清单后 应用商店可见设备变少。
- Dynamic Batching:URP/HDRP 开着时 不生效;老 UI 方案(如 FairyGUI)有时还指望它省 Draw Call,和 SRP 别同时当救命稻草。
- Virtual Texturing / 360 Stereo Capture:当前系列写明 Android 不支持,别在移动上开。
Other Settings:Vulkan 与包名版本
- Vulkan 里 Swapchain 缓冲个数、是否晚取交换链图像 等:移动机上乱改容易 多一次 blit、多一份耗电或兼容问题,不懂就别动。
- Identification:Package Name 上架后想改等于 新应用;Bundle Version Code 给商店比 谁更新 用,和 Bundle Version(给用户看的版本号)不是同一个字段。Minimum 决定 多旧的系统能装;Target 告诉系统你按哪档行为测过,和 权限、后台限制 等政策相关,别长期停在过旧 Target。
Other Settings:脚本后端、ABI、清单相关
- Mono:IL 跑在 Mono VM 上;IL2CPP:先 IL 再 **C++**,再编 .so,出包慢、包体行为不同,但 64 位、混淆、部分渠道 常要求这条线。
- Api Compatibility:**.NET Standard 2.1** 引用面小、包相对小;缺 API 再考虑 .NET Framework,别一上来就拉满。
- IL2CPP 的 C++ 配置:Debug 好查崩溃,Master 体积和速度更好,编一次更久。
- Incremental GC:GC 拆到多帧,换 偶发尖刺 变 多帧轻一点,不是内存变少。
- Target Architectures:系列里写的是 Mono 只能 ARMv7;IL2CPP 才能勾 ARM64。Split APKs by ABI 主要给 Play 按 CPU 下包;国内整包渠道用得少。
- Internet Access / Write Permission / Install Location:直接进 AndroidManifest 行为;Filter Touches When Obscured 用来挡 悬浮窗、系统弹层 下的误触。
Other Settings:脚本编译与 unsafe
- Scripting Define Symbols:配合
#if做 平台/渠道/热更 条件编译;可叠 内置符号 + 自定义符号。 - Allow ‘unsafe’ Code:不开则带 unsafe 指针的 C# 编不过;需与 Player 里该选项一致(见系列 9.2 unsafe 小节)。
Other Settings:剥离与网格优化
- Managed Stripping:High 包最小,最容易把 反射调用到的类型 裁没,线上 NullReference 才爆;备 link.xml 或 **
[Preserve]**。 - Optimize Mesh Data:构建时剃掉「以为用不到」的顶点通道;若运行时 换材质/换 Shader 又用到了这些通道,会出现 缺 UV、法线不对——系列里建议 会运行时换材质就别开。
- Stack Trace:控制 日志带不带脚本栈,Release 有时要关细栈减开销。
Publishing:签名、混淆、自定义模板
- 签名:包名 可以和别人相同字符串,签名 不同则 不能覆盖安装;丢 Keystore 等于丢 更新权,备份和权限要当代码资产管。
- Gradle:Unity 导出或 AS 构建,本质都是 Gradle 任务;改模板前先确认 能干净编过。
- R8 / ProGuard:Minify 打开后堆栈变难读,接完 SDK、定位完崩溃再开 更省时间。
- 自定义 Manifest / Gradle Template:接 权限、多 dex、渠道占位符 时改;动 Launcher Gradle 前先备份 能编过的版本。
- Split Application Binary:主 APK + OBB,Google Play 大体积包 会用到;整包发渠道要确认对方是否支持 OBB。
Android Studio:从 Unity 导出到能出包
- Unity:Player 里填好 包名、图标 等;Build Settings 勾 Export Project,Export 到纯英文路径。
- AS:Open 导出目录;提示选 SDK 时,优先 AS 自带的 SDK,避免和本机另一套 SDK 版本打架。
- Gradle:首次打开常要 Sync / 升级 Gradle,以 能编过 为准(和 Unity 模板、AS 版本强相关)。
- 第一次:Build → Build APK 先编通;报错里常见
gradle.properties仍含android.enableR8——新版默认走 R8,删掉这一行 即可消掉废弃告警;SDK 不匹配 就把 SDK 路径 指到当前 AS 正在用的那一套,或升级 SDK Tools。 - 上架包:Generate Signed Bundle / APK…,配好 Keystore。
- 日常选型:不打算在 原生工程里二开 时,Unity 直出 APK 通常更省事;Export 流程是为 接原生、改 Gradle、后面交互课 打底,最低标准是:导出工程在 AS 里 能完整 Build。
真机调试:Unity 里 Build and Run + 断点
- 真机上的 发热、帧率、GC、插件 和编辑器里不一样,问题多在 Profiler + 日志 + 断点 里现形。
- 手机:开发者选项 里打开 USB 调试(多数机型要先在「关于手机」里连点 版本号 开开发者模式)。连上后 Unity Run Device 里应出现设备名;没有就 Refresh、换线、看驱动。
- Build Settings 勾 Development Build、Script Debugging,需要时再加 Autoconnect Profiler、Deep Profiling、Wait For Managed Debugger。
- 断点顺序(容易踩坑):Build and Run 装好后会弹 Unity 提示——先别点 OK;在 Visual Studio 里 调试 → 附加 Unity 调试程序,选 你的 Android 设备,断点打在
Update、按钮回调等行;再点 OK 让游戏继续,然后去手机上点按钮,断点才会命中。点快了,脚本先跑完,断点就像没挂上。
Unity Remote:省装包,不省「真机包」
- 手机装 Unity Remote,USB 连着;Edit → Project Settings → Editor 里选 Remote 设备(具体下拉项随版本变)。
- 编辑器 Play 时画面推到手机、输入回传,适合 陀螺仪、摇一摇、多点触控 这类编辑器里不好模拟的东西;画面糊、帧率低 是预期,别用它当性能基准。
- 例:调 重力感应 时,用 Remote 可少打几十个 200MB+ 的 APK;要验 真实帧率、IL2CPP、渠道 SDK,仍要 打包装机。
- 插多台 Android 时往往连 第一台;完整测试以 APK 为准。
Android Logcat 包(2019.4+)
- 通过 Package Manager 装 Android Logcat,同一窗口里看 日志、内存、截屏/录像、堆栈工具入口。
- 常用:Auto Run(Build And Run 后自动跟当前包)、按 包名 / 优先级 / Tag / 关键字 过滤;Clear 清屏,Reconnect 断线重连。
- Tools:Screen Capture;Open Terminal 直接进 SDK/platform-tools,可打
adb logcat、adb logcat -s Unity(只扫带Unity标签的行,日志少一大截);Stacktrace Utility、Memory Window 见下节。
截屏录屏、堆栈解析、内存
- Screen Capture:PC 上拉 截图 / 录屏;不录声音;部分机型 screenrecord 不可用,录屏失败先换机或降级分辨率试。
- Stacktrace Utility:USB 在线调试时,主窗口往往已带 C# 行号;它主要解决 测试从线上包拷回来的一大段 native 日志——贴进 Original,符号路径指到
libmain.so / libunity.so / libil2cpp.so(IL2CPP),再 Resolve。符号来自:构建时 Create symbols.zip → Debugging,解压出的 .so 配进 Project Settings → Android Logcat 符号设置。 - Memory Window:切场景前 / 后 各抓一张快照,对比 PSS、Heap Alloc 看有没有 只涨不掉;闪退前抓一张,看是不是 内存顶到系统上限。
ADB 与没有 Logcat 包的老项目
- adb.exe 在 SDK/platform-tools;Logcat 窗口本质是 帮你开好终端 + 连上设备。
- 2019.4 以前 没有 Logcat 包时,习惯用
adb devices看设备,**adb logcat -s Unity** 看脚本日志,**adb install -r xxx.apk** 覆盖装包——和 Logcat 里看到的是同一套日志流。
在 Android Studio 里调 Unity 导出的工程
- 导出时勾 Export Project + Development Build,和上一节一样先 Gradle 能编过。
- Run 装到机子,下方 Logcat 看系统/原生日志,Profiler 看 CPU/内存;日常 Unity 开发仍以 编辑器 + Unity Profiler + Android Logcat 包 为主,AS 更多是 原生同事、Gradle、渠道 SDK 一起改时用。
22.2 面试题精选
基础题
1. 为什么说用 Unity 做安卓游戏时,不一定要先系统学原生 Android 开发?
题目
业务里经常要判断「要不要招一个只懂原生 Android 的人来做 Unity 手游」。从引擎与分工角度,说明 Unity 路线与原生 Android 路线各解决什么问题,以及什么情况下才必须补原生能力。
深入解析
- 原生 Android:用 Java/Kotlin 写 Activity、Fragment、系统 API,面向 应用层。
- Unity 手游:玩法和渲染在引擎里,Android 这边经常是 打 APK、改 Manifest、接 SDK、签名、出渠道包,和「写原生业务 UI」重叠不大。
- 需要 JNI、AAR、Gradle、系统权限踩坑 时,再补 原生 + 构建;否则先把 Unity 出包、真机 Log、Profiler 跑稳即可。
答题示例
我们这边 玩法、资源、渲染 都在 Unity 里;Android 原生那套是 应用 + 系统,和 Unity 客户端 分工不同。招聘时很多岗位先问你能不能 打 Android 包、真机联调、看 logcat,而不是会不会写 Activity 布局。
真要 接渠道 SDK、改 Gradle、和 Java 互调、查 so 崩溃,再系统补 Java/Kotlin 和 Android 工程;平时把 出包 + 调试链路 跑通就够了。
参考文章
- 1.如何使用Unity进行安卓游戏开发
2. Unity 2019+ 在 Hub 里为 Android 发布一般要勾选哪些模块?和「只装编辑器本体」差在哪?
题目
假设新人第一次装 Unity 要做 Android 包,说明 Hub 里 Android 相关模块大致包含什么,以及为何缺了这些就无法在 Build Settings 里正常切 Android、更谈不上出包。
深入解析
- Hub 里勾 Android Build Support,并带上 SDK、NDK Tools、OpenJDK:少了 JDK 编不了 Java 侧,少了 NDK 走 IL2CPP 会挂,少了 SDK 没有平台工具链。
- 只装 Unity 编辑器、不装 Android 模块:Build Settings 里切不到完整 Android 发布管线,相当于只有场景编辑能力,没有 Android Player 那一套。
答题示例
Hub 里要勾 Android Build Support,并带上 SDK、NDK Tools、OpenJDK,这样才有切 Android 平台、打 IL2CPP/Mono、签 APK 所需的工具链。
只装编辑器等于没装 Android Player 与配套 CLI,Build Settings 里无法完成可用的 Android 构建环境,和「能写场景但不会出安卓包」一个道理。
参考文章
- 2.Unity打包安卓-新版Unity2019及以上打包安卓应用程序
3. Android 出包时 ETC2、ETC 和 ETC2 fallback 一般怎么配?
题目
美术问「为什么安卓纹理既要选 ETC2 又要设 fallback」。结合 Build Settings 里 Android 纹理压缩与 ETC2 fallback 的语义,说明各选项解决什么问题、老设备和新设备分别吃到哪条路径。
深入解析
- 原文:ETC2 在 Android 上常用且 支持透明;老设备不支持 ETC2 时可用 ETC。
- 全局选 ETC2 时,在 ETC2 fallback 里配置不支持 ETC2 时 RGBA 的存储:32-bit / 16-bit / 32-bit 半分辨率,在 未使用 ETC2 作压缩 时多数情况备用 32-bit,具体还看 GPU 支持。
答题示例
ETC2 是 Android 侧常用、带透明的压缩;ETC 照顾更老的 GPU。
ETC2 fallback 管的是「设备啃不动 ETC2 时 RGBA 怎么存」:要 画质 用高位宽,要 省内存 可降 bit 或半分辨率,和「主格式选 ETC2」是两层开关。
参考文章
- 4.Unity打包安卓-设置相关-BuildSettings
4. 包名(Package Name)都撞了的话,Android 靠什么区分是不是同一个应用、能不能覆盖安装?
题目
两个团队不小心起了同一个 com.xxx.yyy,从 Android 安装与更新模型说明:包名 和 签名 各自承担什么角色,和 Unity Player Settings 里哪几项对应。
深入解析
- 原文:Package Name 是应用 ID,商店与系统靠它识别;签名 区分 同一包名下的不同开发者,防止 恶意替换。
- 举例:同包名不同签名 不能随意覆盖;签名由 Keystore / 密钥 持有。
答题示例
包名 是应用身份的主键;签名 证明「这次安装是不是同一开发者签出来的」。
Unity 里 Package Name 在 Identification 配;签名 走 Publishing / Keystore。撞包名时,签名不同 往往就 装不上或无法覆盖,这正是签名机制要防的。
参考文章
- 7.Unity打包安卓-设置相关-OtherSettings-Vulkan设置和身份证明
- 11.Unity打包安卓-设置相关-PublishingSettings-密钥管理器
5. 什么时候该 Unity 里直接 Build APK,什么时候该 Export Project 再用 Android Studio?
题目
团队里有人坚持「所有包都必须经 Android Studio 过一遍」。结合本系列原文对 Unity 直出 与 导出 Gradle 工程 的定位,说明各自适用场景,以及 AS 路线最低要练到什么程度。
深入解析
- Unity 直出:不嵌原生、不接复杂 Gradle 模板时,迭代最快,与 Android Studio 打包 一文中的结论一致。
- Export + AS:需要 原生二开、改 Gradle/清单、与 Android 工程深度集成 时走;平时以 能打开导出工程并成功构建 为底线能力。
答题示例
不做 Activity 嵌入、渠道 Gradle、自定义 manifest 流水线 时,Unity 里直接出 APK 通常更省事。
Export Project 是给 要在 AS 里改 Java/Kotlin、Gradle、签名与渠道配置 用的;按原文,系列目的是先保证 导出工程能编通,再谈后面交互与 SDK。
参考文章
- 13.AndroidStudio打包安卓
6. Minimum API Level 和 Target API Level 各管什么?只调一个行不行?
题目
策划问「能不能把最低版本设得很低以覆盖老机,同时 Target 设很高过审」。结合 Identification 里两项的语义,说明 谁能装、系统按哪档行为约束你,以及和 权限、后台限制 等政策的关系(答出「两个都要配、职责不同」即可)。
深入解析
- Minimum API Level:设备 系统版本低于此值 则 无法安装;决定 机型覆盖下限。
- Target API Level:声明 你按哪档 API 行为做过适配;系统 不应 为了兼容无限替你兜底旧行为,权限、后台、存储分区 等规则会随 Target 抬高而变严(具体以各 Android 版本行为为准)。
- 两者 不能互相替代:一个管 能不能装,一个管 装上去之后系统怎么对待你。
答题示例
Min 是门槛:老系统低于它就 装不了。Target 是「我跟新系统规则对齐到哪一步」:设低了可能 审核/商店侧 不认可,设高了要在真机上 按新权限与后台规则 测全。
实际项目里一般是:Min 覆盖业务要支持的最低机,Target 跟进渠道/商店要求,再拉清单测一轮 权限与兼容性。
参考文章
- 7.Unity打包安卓-设置相关-OtherSettings-Vulkan设置和身份证明
进阶题
1. 老版 Unity 文档里说 NDK「可选」,什么时候又变成必选?和 Mono / IL2CPP 怎么对应?
题目
维护一个 Unity 2018 时期的项目,策划问能不能「为了省磁盘不装 NDK」。从脚本后端与出包方式回答:什么情况下可以不装,什么情况下必须装,装错版本会怎样。
深入解析
- 原文:Mono 后端 可以不发 NDK;一旦要打 IL2CPP(把 IL 转成 C++ 再编进 so),就必须有匹配版本的 NDK。
- 版本约束:Unity 2018 对应 NDK r16b,Unity 2017 对应 r13d,应按原文选用,乱用版本常见编译失败或链接错误。
答题示例
NDK 用来编 IL2CPP 生成的原生代码;项目用 Mono 且不需要 IL2CPP 管线时可以不装。
一旦切 IL2CPP 或目标平台要求原生库参与链接,NDK 就变成硬依赖,还要按 Unity 版本选 r16b / r13d 这类匹配组合,否则多半是编不过或运行期崩。
参考文章
- 3.Unity打包安卓-老版Unity2018及以下打包安卓应用程序
2. 勾选 Export Project 后 Symlink Sources 是干什么的?什么时候值得开?
题目
程序要把 Unity 工程导出给原生同事二开。说明 Export Project 与 Symlink Sources 各自改变什么产物行为,以及 Symlink 对「反复导出还要保留 Java/Kotlin 改动」的意义。
深入解析
- Export Project:不再直接出 APK,而是 Gradle 工程 供 Android Studio 使用。
- Symlink Sources:仅在 Export Project 时可勾;决定是否 共享 Java/Kotlin 源 于 Unity 与导出目录之间;重新导出 时,对导出侧源码的修改是否更易保留(按原文「二次开发建议勾选」)。
答题示例
Export Project 把活交给 AS + Gradle;Symlink 让 Unity 与导出工程 共用一份 Java/Kotlin 源,适合你要在 导出目录里改原生代码、又经常 从 Unity 再导一版 的迭代。
不需要二开原生、只要 Unity 直出 APK,就 不必 走 Export + Symlink。
参考文章
- 4.Unity打包安卓-设置相关-BuildSettings
3. Mono 只能 ARMv7、IL2CPP 能勾 ARM64——和「上架 64 位」是什么关系?
题目
海外发行同事提 Google Play 要求包内含 64 位原生库(政策细节以官方为准)。结合系列里 Scripting Backend 与 Target Architectures 的表述,说明:为什么 Mono 路线难以单独满足「只要 64 位」,以及 IL2CPP + ARM64 在工程上通常扮演什么角色。
深入解析
- 系列正文:Mono 下 Target Architectures 只能 ARMv7;IL2CPP 才能勾选 ARM64 等更多 ABI,并把 C# → C++ → .so 打进包内对应
lib/arm64-v8a等目录。 - ARM64 在正文里关联 性能 与 大于 4GB 地址空间 的讨论;是否只发 32 位、是否 ARMv7+ARM64 双包,取决于 渠道与商店合规,需在 Player Settings 与 分包策略 上对齐。
- 面试常追问(政策补充,非系列正文):Google Play 对新应用有 64 位原生库 要求,细则以 Support 64-bit architectures 为准;国内渠道规则不同,需分别核对。
答题示例
系列里写得很死:Mono 只能 ARMv7,没有 ARM64 这条腿;要上 arm64-v8a 的 .so,在 Unity 侧通常走 IL2CPP,并在 Target Architectures 勾 ARM64。
Play 合规 是 商店政策 + 包体里 ABI 问题:要和 机型覆盖、Min API、ABI 列表、是否拆 APK 一起算,避免「本地能编、上架拒收」。
参考文章
- 8.Unity打包安卓-设置相关-OtherSettings-配置
4. Unity 导出工程在 Android Studio 里首次构建时,android.enableR8 与 SDK 路径问题分别怎么处理?
题目
CI / 原生同事 拉下 Unity 导出的 Gradle 工程后构建失败。日志里出现 android.enableR8 已废弃、SDK Tools 版本不匹配。按 「先 Gradle 模板、再 SDK 对齐」 说明:改哪个文件、为什么优先用 AS 自带 SDK,以及和 Unity 本机 External Tools 路径不一致时的协作习惯。
深入解析
- R8:新版 Gradle/Android Gradle Plugin 默认用 R8 做压缩与混淆,**
gradle.properties里的android.enableR8已废弃**;删掉该行,避免与当前插件行为 重复声明。 - SDK:Unity 的 Android SDK 路径 与 AS 当前工程用的 SDK 不是同一路时,Build Tools、platforms 版本可能对不上;以能编过 AS 工程为准,在 AS SDK Manager 对齐,或把工程 local.properties / SDK 路径 指到团队统一目录。
- 协作习惯:导出工程多在 AS 侧 调 Gradle,优先用本机 AS 已安装 SDK 可减少「Unity 能编、AS 不能编」的扯皮。
答题示例
先打开 **
gradle.properties**,把android.enableR8这种 废弃开关 清掉,再 Sync。SDK 报错就看 AS 里选的 SDK 路径和 Build-Tools 版本,跟 Unity Edit → Preferences → External Tools 是否一致;不一致就 统一到团队约定的一套 SDK,或 升级 Tools。别在两边各维护一套还不写进文档。
参考文章
- 13.AndroidStudio打包安卓
5. 真机断点调试时为什么要「先附加调试器再点弹窗 OK」?顺序反了会怎样?
题目
新人用 Build and Run 后立刻点掉 Unity 弹窗,结果断点永远不进。结合 Unity 内连接真机断点调试 的推荐步骤,说明 Wait For Managed Debugger、附加 Unity 调试器 与 点击 OK 的先后关系。
深入解析
- 原文:弹窗未点 OK 前,先在 Visual Studio 附加 Unity 调试程序 到 对应设备 并设好断点,再点 OK 让脚本继续跑,才能命中 托管断点。
- 顺序反了:进程已继续跑过要调试的入口,或调试器未就绪,常见 断点不触发。
答题示例
Wait For Managed Debugger 打开时,应用会 等调试器;你要先 附加到设备进程,断点布好,再 放行,否则脚本先跑完关键路径,断点就像「没接上」。
这和编辑器里 F5 不同,真机托管调试 是 附加式 的,顺序错了就只能 重跑一轮。
参考文章
- 14.调试相关-Unity内调试安卓应用程序
深度题
1. 为什么出包教程常强调「输出路径和工程路径不要中文」?从工具链与脚本角度简述可复现类问题,而非泛泛谈「不稳定」。
题目
团队里有人把工程放在含中文的桌面目录,构建偶发失败或控制台里报路径、编码相关错。结合 Unity 会调用外部 JDK、Android SDK、NDK 且老版依赖 环境变量与命令行 的事实,说明这类路径风险主要来自哪里,以及工程上的规避策略。
深入解析
- 原文明确:发布路径 与 工程路径 都不要中文;老版还要配 JAVA_HOME、Path,外部工具常通过 命令行 引用这些路径。
- Windows 下 非 ASCII 路径 在 控制台、批处理、JDK / SDK / NDK 自带工具 中更容易出现 编码、引号转义、路径截断 一类问题;构建链里任一环节解析失败都会表现为「偶发找不到文件」。
- 规避:全 ASCII 盘符与目录、短路径、CI 固定工作区;避免「本机可复现、换目录就炸」。
答题示例
Android 构建会拉起 JDK、SDK、NDK,很多步骤是 命令行 + 拼接路径;中文或特殊符号在 控制台编码、工具链参数 里容易踩坑,表现就是 偶发找不到文件、乱码、脚本中断。
工程上统一把 工程与输出 放在 纯英文路径,CI 与用户目录解耦,比事后查「为什么这台机器不行」便宜得多。
参考文章
- 2.Unity打包安卓-新版Unity2019及以上打包安卓应用程序
- 3.Unity打包安卓-老版Unity2018及以下打包安卓应用程序
2. Managed Stripping 开到 High、又开了 Optimize Mesh Data,线上可能出哪类「编译期没问题、运行期才炸」的坑?
题目
Release 包体要极限压缩:把 Managed Stripping 拉高、能勾的优化都勾上。结合原文对 High 剥离 与 Optimize Mesh Data 的警告,说明典型故障形态(反射/序列化/代码裁掉、运行时换材质等),以及工程上常用的兜底手段。
深入解析
- High:最大化剥离 C#,可能 误删 实际会通过 反射 调到的类型;link.xml、[Preserve] 用于 显式保留。
- Optimize Mesh Data:构建时 去掉未用顶点属性;若 运行时 会 换材质/着色器 依赖原先以为未用的通道,则与原文警告冲突。
答题示例
High 常见坑是 反射、序列化、配置驱动 调到的类型被 Link 裁没,表现为 Null、MissingMethod、加载失败;用 link.xml / Preserve 把 不能裁的边 钉死。
Optimize Mesh Data 的坑是 运行时改材质 需要 顶点属性 时,构建时以为没用 剥掉了,表现为 显示错误、缺通道;按原文:会在运行时换着色器就不要开。
参考文章
- 10.Unity打包安卓-设置相关-OtherSettings-优化和堆栈跟踪
3. 线上崩溃日志只有 libunity.so 地址时,Stacktrace Utility 要解决什么前置条件?符号从哪来?
题目
测试发来一段 发布包 里拷出来的 原生堆栈,没有脚本行号。说明 Stacktrace Utility 与 符号路径、Debugging 符号包 的关系,以及为什么 USB 连着 Logcat 时往往用不上这套离线流程。
深入解析
- Utility:把 Original 里的 原始堆栈 配符号后解析到 Resolved;需配置 libmain.so、libunity.so、libil2cpp.so(IL2CPP) 等路径。
- 符号来源:构建时 Create symbols.zip 选 Debugging 会得到含 .so 的包;解压路径配进 Project Settings 里 Android Logcat 相关符号设置。
- 在线调试:USB 连着时主 Logcat 往往已能看 托管/脚本侧 信息,离线文本才强依赖 Utility + 符号。
答题示例
发布版日志若是 只有地址的 native 堆栈,要把 对应版本的 .so 指给解析器,否则只能看到 PC 偏移,看不到 脚本映射。
Debugging 符号 zip 就是给这一步用的;平时连着真机调,多数问题直接在 Logcat 主窗口 里已经带上下文,Utility 主要是 事后看崩溃文件 的场景。
参考文章
- 18.调试相关-AndroidLogcat-堆栈跟踪实用工具
- 4.Unity打包安卓-设置相关-BuildSettings
4. 为什么接渠道 SDK、发正式包时,Minify/R8 常常最后才开?线上要防什么?
题目
主程要求 Release 必开 R8/混淆 减体积、防逆向;你担心 堆栈看不懂、SDK 初始化失败。结合 Publishing 里 Minify、Use R8 与 构建耗时、调试成本 的表述,说明 何时开、如何验证、和崩溃符号的关系。
深入解析
- 系列里:Minify 会 拉长构建,且 让调试变复杂,一般 正式包 才开;Use R8 可在 ProGuard 与 R8 间切换(视 Unity/Gradle 版本)。
- 混淆后 类名/方法名 变化,Java 侧崩溃 与 Unity 托管栈 要靠 mapping / 符号包 还原;这和 native 堆栈 + Debugging 符号 zip 是两条线,都要在 发版流程 里按 版本号 存档。
- 工程上:先 不接混淆 把 SDK 跑通,再 开混淆做回归,必要时为 SDK 配 keep 规则(自定义 ProGuard 文件在 Publishing 里可配)。
答题示例
Minify/R8 不是「勾上就走」:先保证 功能与 SDK 初始化 在 不混淆 下稳定,再开混淆做 全量回归,否则 线上偶现 很难区分是 业务 bug 还是 被 shrink 掉/改名。
发版时 mapping、symbols.zip 与 版本号 一一归档;线上崩了才能 反混淆、才能 还原堆栈,否则 查不动。
参考文章
- 11.Unity打包安卓-设置相关-PublishingSettings-密钥管理器
- 12.Unity打包安卓-设置相关-PublishingSettings-其他
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com