期末练习:发布游戏
everything from tab 01–05 · signed release build on a real phone
课程的最后一道练习:把 Arena —— 波次、敌人、触控操作全都算上 —— 以签好名的 release build 装到一台真手机上,连续五分钟稳住帧率(手机扛得住就 60 FPS,任何时候都不低于 30),杀掉 App 重开还记得你的进度。
复用的东西
不是编辑器里的截图 —— 而是手机上那个别人也能装的 App 图标。
第 1 部分 —— 清理场景
打开 Arena.unity —— 这是你从第 01 部分一路养大的那个场景 —— 检查 GameDirector 还留着那些出生点。
把测试时留下的东西删干净:多余的相机、乱放的灯、你挪到一边的方块。
场景里必须正好只有一个 AudioListener、一个 EventSystem 和一个 CinemachineBrain。
确认第 03 部分的触屏 Canvas 还在,而且游戏跑在手机上时它会自动开启。
第 2 部分 —— 配置 build
Project Settings → Player
Company Name your studio // not DefaultCompany
Product Name Arena
Package Name com.yourstudio.miniarena // permanent
Version / Bundle Code 1.0.0 / 1
Default Orientation Landscape Left
Scripting Backend IL2CPP
Target Architectures ARMv7 + ARM64 // ARM64 is mandatory
Minimum API Level 24
Managed Stripping Medium
Graphics APIs Vulkan, OpenGLES3 // remove OpenGLES2
URP Asset (mobile)
Shadow Max Distance 40
Cascade Count 1
HDR off
MSAA disabled
Render Scale 0.85
Assets/link.xml
preserve SaveData // or stripping deletes itvoid Awake()
{
Application.targetFrameRate = 60;
QualitySettings.vSyncCount = 0;
Screen.sleepTimeout = SleepTimeout.NeverSleep;
DontDestroyOnLoad(gameObject);
}第 3 部分 —— 第一次 build 一定有问题
这在你预料之中。先出一个 Development Build,装到手机上,边玩边读 adb logcat。只在真机上才出现的 bug,才是这道练习真正的重点。
adb devices # is the phone actually connected?
adb logcat -c && adb logcat -s Unity # clear, then watch only Unity
# after the build
adb install -r Builds/arena-dev.apk
adb shell monkey -p com.yourstudio.miniarena 1几乎人人都会踩的五个坑
材质变粉色 —— shader 没转成 URP。转换材质后重新 build。
按钮点了没反应 —— 要么缺 EventSystem,要么有个铺满全屏的透明 Image 把 raycast 全吃了。
存档是空的 —— IL2CPP stripping 把 SaveData 裁掉了。把它加进 link.xml。
真机 20 FPS,编辑器 200 FPS —— 是实时阴影和后处理。检查一下 URP asset。
UI 被刘海切掉 —— 触屏 Canvas 上少了 SafeAreaFitter。
第 4 部分 —— 正式版 build
创建 keystore,存到项目外面,备份两份。弄丢了你可能就没法再更新这个 App。
在提交任何东西之前,先把 *.keystore 加进 .gitignore。
取消勾选 Development Build,勾上 Build App Bundle,然后 build 出 .aab。
另外留一个签好名的 .apk —— 你发给朋友装的就是它。
怎样算做完
- ✓App 装在真手机上,从它自己的图标启动,而不是从 Unity。
- ✓只用触屏就能打完完整一圈:移动、转向相机、放出全部三个技能、击杀一个敌人。
- ✓在带刘海的手机上每个 UI 元素都在安全区内,而且锚点设得让平板也不会把布局撑坏。
- ✓把 App 切到后台再强杀,重开后血量、位置和金币都还在。
- ✓连续玩五分钟仍然不低于 30 FPS —— 量的是第 5 分钟,不是第 1 分钟。
- ✓整局玩下来,adb logcat -s Unity 里一条 exception 都没有。
- ✓有一个签好名的 .aab,是在没勾 Development Build 的情况下 build 出来的。
- ✓别人把 .apk 装到他们自己手机上,跑起来了。
需要达到的数字
| 指标 | 目标值 | 原因 |
|---|---|---|
| 第 5 分钟的 FPS | ≥ 30 | 手机发热会降频,只有第 5 分钟的数字才算数。 |
| .aab 包体大小 | ≤ 150 MB | 超过 150 MB,Google Play 就要额外配置分包下载。 |
| 冷启动到可操作的耗时 | ≤ 5 s | 黑屏时间再长一点,玩家就会直接关掉 App。 |
| 内存占用 | ≤ 600 MB | 超过这个数,3 GB 内存的手机一切后台就会杀掉你的 App。 |
| logcat 里的异常 | 0 | 每帧一个 NullReference,是个悄无声息的帧率杀手。 |
想再多做点
把 .aab 以 internal test 上传到 Play Console,再从 Play Store 装到自己的手机上。
加一个设备档位判断,在内存低于 3 GB 的手机上降低 render scale 和阴影距离。
同一份工程再 build 一版 iOS,在档次相近的硬件上对比帧率。
加一个可开关的游戏内 FPS 和内存浮层,这样测试的人就能报给你真实数字。
整门课到这里就结束了
你从“变量是什么”起步,最后做出一个跑在手机上的签名 build。整条流水线你已经走通了一遍。
从这往后的功课是深度而不是广度:更好的动画、更聪明的敌人、真正的关卡设计、属于自己的美术风格。
下一个该做的是这样一款游戏:一种玩法机制、五分钟内容,但你真的把它做完了。在这一行里,最稀有的技能就是把东西做完。