关于 scenario-unity-mobile
面向 Unity 移动游戏开发者的技能,覆盖性能、资源导入、输入界面、变现逻辑和商店发布。它以持续运行表现和实际构建产物为验证重点,并提供 Android 与 iOS 的审查及发布流程。
主要功能
- 01评估持续帧率与热管理
- 02审核移动端渲染和资源格式
- 03构建触控输入与安全区界面
- 04处理内购、广告及隐私流程
- 05检查 Android 与 iOS 发布产物
适用场景
- 01为低端手机设定并验证帧预算
- 02调整纹理、音频和渲染设置
- 03测试安全区布局与触控控制
- 04检查购买、奖励和广告回调逻辑
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-unity-mobile安装后在 Claude Code 中输入/scenario-unity-mobile确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/ut_mobile.pyscripts/AgentKit/Mobile/MobileAudio.csMobileBuild.csMobileImportRules.csMobileStartup.csMobileTextures.csMobileTiers.csMobileUi.csMobileXcodePostprocess.csscripts/Runtime/AgentKit.Mobile.Runtime.asmdefAndroidDiagnostics.csDeviceSoakLogger.csMobileTierPolicy.csMonetization.csSafeAreaFitter.csSafeAreaMath.csTouchStick.csscripts/Runtime/Iap5/AgentKit.Mobile.Iap5.asmdefIap5Store.csscripts/Runtime/LevelPlay9/AgentKit.Mobile.LevelPlay9.asmdefLevelPlayAds.cs详细介绍
Unity 移动端(移动端专家)
专业的移动端开发,意味着游戏在一台使用三年的手机上运行 20 分钟后仍能保持帧率、启动迅速、可从商店安装,而且绝不会重复扣费或重复发放奖励。基本原则:为持续帧率做好预算;针对设备实际获取的数据证明每项设置都正确(导入格式、构建后的资源包、导出的 Xcode 项目);并将商店、SDK 和资金相关代码视为可能遭遇糟糕事件顺序的契约。目标:Unity 6000.3.21f1、URP 17.3、Input System 1.20,以及搭载 Xcode 26.6 的 macOS。如果此处提及的同级技能不在你可用的技能中,请让用户安装它
(npx skills add scenario-labs/skills --skill <name>);若无人值守,则根据工具架构继续操作并指出这一缺口。
必备背景: scenario-unity-expert(渠道、审查循环、6.3 陷阱)。工具包:
scripts/ut_mobile.py(导入 ut_env、ut_run、ut_stat),编辑器任务位于
scripts/AgentKit/Mobile/,运行时代码位于
scripts/Runtime/。
原则(专家补充)
- 规划持续帧预算,而非峰值预算。 约占 1000/fps 的 65%(60 fps 时为 10.8 ms,30 fps 时为 21.7 ms);在最低端手机上以 p95 和最大值为依据,进行短时突发测试,并冷却 10 到 15 分钟;假设启用了 vsync,因此错过一次刷新就会使帧率减半(Unity 移动端电子书)。设备过热时,只有在 GPU 是瓶颈的情况下才优先降低渲染缩放:分辨率几乎无法改善 CPU 受限的帧(6.3 Manual)。通过合成热事件证明策略,而不是让手机过热(d5O4Uw6gPBI [00:04:21])。编辑器中的耗时数据仅供参考;绘制次数和 SetPass 次数才是稳定的编辑器证据(已观察到)。
- 检查实际格式,然后锁定规则。 如果 GPU 无法采样某种纹理,就会在 CPU 上将其解压为 RGBA32(6.3 Manual);未设置 ASTC HDR 覆盖的 HDR 贴图导入后会变为 ETC2_RGBA8(已观察到)。UI 和人脸使用 ASTC 4x4,默认使用 6x6,大型环境贴图使用 8x8 [已添加];crunch 对 ASTC 无效。音频:源文件使用 WAV,单声道 SFX 最高为 22,050 Hz,200 KB 以下使用 ADPCM,仅对约 400 KB 以上的文件启用 Streaming(电子书)。
AssetPostprocessor可确保新资源符合规范(Unity Enterprise Support,j4YAY36xjwE [00:19:07])。 - 移动端 URP 并非只需调低滑块的 PC URP。 Depth Priming 设为 Disabled(Android、iOS 和 TBDR 不支持),启用 Native RenderPass;除非需要采样,否则关闭 Depth 和 Opaque 纹理;关闭 HDR 或使用 32 位;关闭软阴影;Store Actions 设为 Auto 或 Discard(6.3 Manual)。每个 Quality 层级使用一个 URP 资源;为 Android 启动的批处理编辑器仍报告 Quality 为“PC”(已观察到;2J0kDtUGlrY [frame 00:10:28] 中也出现了相同陷阱)。
- 发布构建应可根据环境复现。 Unity 从不保存密钥库密码:在构建过程中通过环境变量设置;Google 不接受调试密钥库(6.3 Manual;LlamAcademy,GTaXWgKz0e8 [00:06:24])。关闭 Development Build;从首次上传起就将符号文件包含在包中:对于符号文件上传前收到的崩溃,Play 永远不会进行符号化处理(6.3 Manual)。检查构建完成的包,而非设置。
- Android 主线程与启动画面共享预算。 大多数游戏 ANR 都发生在应用转入后台时:不要在
OnApplicationPause中执行繁重操作;在各个里程碑之后分阶段初始化 SDK;随包提供符号文件;读取签名、下次启动时读取上一次退出原因,并排除占据 ANR 大头的低收入设备(Unity Android team,pezwIhA0e04 [00:27:24]、[00:25:12]、[00:13:13]、[00:41:40]、[00:29:02])。Resources 索引和首个场景的Awake会在启动画面显示期间运行(j4YAY36xjwE [00:33:59]);加载场景使用CallReportFullyDrawn报告实际可交互帧(6.3 Manual)。 - 涉及资金的代码必须具备幂等性。 验证、发放,然后调用
ConfirmPurchase;通过交易 ID 对进行中和已持久化的交易去重;来自OnPurchasesFetched的待处理订单也走相同流程;确认时出现FailedOrder,则使用保留的订单重试,绝不再次发放;只购买已获取的Product对象;Google 返回空结果时绝不撤销购买;显示商店本地化价格;将jwsRepresentation交给归因 SDK(IAP 5 docs;Unity,szS2KMxZsl4 [00:07:27]、[00:09:28]、[00:11:38])。无论回调顺序如何,都在OnAdRewarded中发放奖励广告奖励。 - 触控由事件和虚拟设备处理;HUD 位于单一安全区域面板中。 使用 EnhancedTouch,绝不在 Update 中使用
Touchscreen.current;屏幕控件应生成虚拟 Gamepad;拇指控件使用 Constant Physical Size(Input System team,ptvjumIHxYg [00:20:29])。movementRange表示半径(已观察到)。启用在安全区域外渲染,并将 HUD 放入SafeAreaFitter面板(Chema Damak,PLQ4ywB13eg [00:10:53]);UI Toolkit 的 top =Screen.height - safeArea.yMax(测试已证实)。Device Simulator 只支持一根手指,不提供性能数据,不定义UNITY_IOS,也不支持原生插件(6.3 docs)。 - SDK 和商店都是契约。 在首次广告请求前完成用户同意流程,在首个里程碑后初始化广告 SDK,前 10 到 15 分钟内不进行任何变现;在玩家受阻时提供优惠(Creauctopus,ILv7GzDgteQ [00:01:58]、[00:09:00]);iOS 上配置 SKAdNetworkItems 和每个 SDK 的隐私清单,API 33+ 使用 AD_ID(LevelPlay docs;6.3 Manual);进行跟踪时提供 ATT 文本 [已添加];依据 SDK 供应商的指南填写 Data safety;创建 IAP 商品前,先上传到一个内部测试轨道(GTaXWgKz0e8 [00:09:06];UXl_C3ZnRLc [00:02:28])。6000.3.21f1 默认使用 IAP 4.15.1 和 LevelPlay 8.10.1:首先固定使用 5.4.3 和 9.5.1。
首先确定
商店(Play 需要 AAB);最低规格设备列表(GPU 系列决定使用 ASTC 还是 ETC2);各档位的目标帧率;下载预算;屏幕方向;广告网络、IAP 商品、同意法规(GDPR、CCPA、面向儿童)以及后端是否验证收据;签名材料(keystore 路径和环境变量名称、Apple 团队 ID:由人工保管);是否连接了手机(此处没有:设备步骤改为交接)。默认值:Mobile_High 为 60 fps,Mobile_Low 为 30 fps(发布 Low,由总监决定是否升级);ASTC 6x6;最低 API 25;目标 API 36;iOS 15;IL2CPP ARM64;先用 Vulkan,再用 OpenGLES3;初始采用 Minimal 剥离。
工作流
- 基线。
MobileTiers.AuditRendering、MobileBuild.AuditPlayerSettings、MobileTextures.AuditTextures、MobileAudio.AuditAudio、MobileStartup.AuditStartup、ut_mobile.code_scan(P)、ut_mobile.package_check(P),均使用build_target="Android"。门槛: 列出发现的问题,记录 Editor Quality 级别。 - 档位和热状态。
MobileTiers.ApplyTiers;通过 PlayMode 合成Feed事件运行MobileTierDirector。门槛:AuditRendering错误数为 0;打开各档位的 捕获结果;热测试降低 lodBias 和(仅 GPU 瓶颈时)渲染比例,并恢复二者。 - 资源。 依次运行
FixTextures、FixAudio、AuditMeshes,然后按目标平台运行ImportedFormats和ImportedAudio;为MobileImportRules使用import_rules.json。门槛: 错误和警告数均为 0;全部使用 ASTC;导入后的体积有所下降;新资源符合规范;任何 Max Size 降低前后都要捕获结果。 - 输入和 UI。
SafeAreaFitter、BuildTouchHud、FloatingTouchStick。门槛:SafeAreaTests和TouchInputTests通过;CaptureSafeArea显示适配后的 HUD 清晰可见, 而未适配的 HUD 被遮挡。 - 帧预算。 按档位运行
AgentProfile.PlayModeTimings、budget_verdict(csv, fps); 将DeviceSoakLogger加入开发版本。门槛:持续运行判定通过;设备浸泡测试列为假设项。 - 变现。 固定软件包版本;逻辑放在
PurchaseLedger、RewardGate、AdPacing、AdsInitGate中;适配器包括Iap5Store(验证、价格、jws)和LevelPlayAds(初始化前设置隐私标记)。门槛:MonetizationTests通过;适配器可针对固定的软件包版本编译;code_scan和package_check无问题。 - Android 发布。 运行
make_keystore,通过MobileBuild.BuildAndroid构建,并设置env=keystore_env(ks)。门槛:构建成功;aab_findings错误数为 0(不可调试、16 KB 页、 符号、投放广告时的 AD_ID);bundletool_sizes未超出预算,否则按体积查看 Build Report, 然后使用 Play Asset Delivery;不持久化密码。 - iOS 发布。 在
Assets/Plugins中放置隐私清单,运行BuildIos、xcode_facts+xcode_findings。门槛:构建成功,保留原因,并报告目标 GUID;向人工展示ios_archive_plan命令(归档、导出到 App Store、瘦身报告),仅在获批后运行。 - 设备和商店交接。 使用
soak_verdict判定浸泡测试 CSV,使用原生 GPU 性能分析器;检查 Android vitals,进行 ANR 分流并查看ExitInfo;测试沙盒购买和恢复;先运行 LevelPlay 测试套件,再移除;执行 Play Console 和 App Store Connect 步骤(流程 M13)。
数值
| 数值 | 相关说明 | 来源 |
|---|---|---|
| 16.67 / 10.83 ms,33.33 / 21.67 ms | 60 和 30 fps 下的原始 / 持续(65%)预算 | 电子书 |
| 10 到 15 min;20 到 30 min | 设备采集之间的冷却时间;浸泡时长 | 电子书;[已添加] |
| 最多 1 ms CPU | 低端移动设备上每个启用的摄像头 | 电子书 |
| 8 到 0.89 bpp | ASTC 4x4 到 12x12 | 6.3 Manual |
| < 200 KB / > 350 到 400 KB;22,050 Hz | 音频负载类型分类;移动设备 SFX 采样率上限 | 电子书 |
| 200 MB / 100 MB | Play 上的 AAB 基础模块 / APK;也是 iOS 蜂窝网络下载限制(200) | 6.3 Manual |
| 16 KB(p_align 0x4000) | Android 15+ 页面中每个原生库的 LOAD 段 | 版本差异 |
| API 25 / 36 | 6.3 最低要求 / 自 2026-08-31 起的 Play 目标版本(6.5 将最低要求提高至 26) | 版本差异 |
| iOS 15、A8;Xcode 26 + iOS 26 SDK | 6.3 最低要求;自 2026-04-28 起的 App Store 要求 | 版本差异 |
| 5 s(部分 Samsung 设备上为 10 s);128 bytes | ANR 超时;退出状态摘要 | pezwIhA0e04 [00:02:01],[00:42:13] |
| 3 天 | Google 会退还未确认的购买 | IAP 5 docs |
| 10 到 15 min;每 3 min | 免变现启动时长;里程碑后的插屏间隔 | ILv7GzDgteQ(启发式规则) |
| 54998 到 55511 | iOS 远程性能分析的出站端口 | 6.3 Manual |
| 0.125 到 0.925 | 应用于屏幕摇杆值的默认 Gamepad 摇杆死区 | 观察所得 |
质量门槛
- 可测量: 每项审核均为 0 个错误(警告须有合理说明);
ImportedFormats全部为 ASTC;NUnit (SafeAreaTests、TouchInputTests、MonetizationTests、TierDirectorTests)失败数 == 0;budget_verdict持续通过;aab_findings和xcode_findings错误数为 0;bundletool_sizes符合预算;code_scan和package_check错误数为 0;在设备上,soak_verdict至少通过 20 分钟。 - 视觉: 档位和安全区域的截图通过
image_checks并已打开;每次降低 Max Size 后均检查模糊前后的效果。
常见错误
| 错误 | 表现 | 修复 |
|---|---|---|
| 在 Editor 中按 16.7 ms 进行性能分析 | 在 Mac 上运行正常,但在手机上运行 10 分钟后便开始降频 | 预算按 65% 计算,进行设备长时间测试,关注 p95/最大值 |
| 在移动端目标上使用 PC 质量级别 | 捕获结果使用 PC_RPAsset,或发布了 PC 级别 | 使用 ApplyTiers(排除 PC)和 SetEditorQuality |
| 对 CPU 受限的游戏通过分辨率应对温度升高 | 画面变模糊,速度却几乎没有提升 | 仅在受 GPU 限制时调整渲染比例;调整 lodBias、阴影 |
| 覆盖为 RGBA32;HDR 地图未使用 ASTC HDR | 1024 px 纹理占用 5.3 MB;HDR 被导入为 ETC2_RGBA8 | 使用 FixTextures,检查 ImportedFormats |
| 流式传输较小的片段;音乐使用 Decompress On Load | 每个流多出 200 KB 开销;完整 PCM 驻留在内存中 | 使用 FixAudio(按大小分桶) |
| 只在 GUI 中设置一次密钥库 | 下一次批量构建失败,或发布了使用调试签名的版本 | BuildAndroid 读取环境变量 |
| 上传 Development Build;延后上传符号 | 上传失败;早期崩溃记录从未进行符号化 | 使用 aab_findings;在第一个 bundle 中包含符号 |
在 IPostGenerateGradleAndroidProject 中编辑 Gradle | 增量构建产生过时输出 | 对自定义模块使用 AndroidProjectFilesModifier,或进行干净构建 |
在 OnApplicationPause 中保存;在第一个 Awake 中初始化 SDK | 暂停时出现 ANR;启动时在启动画面下耗时过长 | 使用检查点;分阶段初始化 SDK;运行 AuditStartup |
| IAP 5 项目中使用 IAP 4 代码;留下 LevelPlay 8 文件夹 | 编译错误;9.x 软件包旁存在 9 之前的 SDK 文件 | 固定软件包版本,使用 package_check |
将 OnPurchaseConfirmed 视为成功 | FailedOrder 被悄然丢弃 | 使用保留的 PendingOrder 重试 |
| IAP 5 后归因 SDK 无法工作 | iOS 收入缺失,且没有错误提示 | 使用 OnAppleJws,然后进行设备购买 |
在 OnAdClosed 中发放奖励;测试套件仍留在发布版本中 | 奖励缺失;发布版本中包含验证调用 | 使用 RewardGate;运行 code_scan |
| HUD 锚定到画布;把 Simulator 当作验证依据 | 按钮位于刘海下方;未测试多点触控 | 使用 SafeAreaFitter;在设备上检查 |
| 任意 Gamepad 连接时隐藏 HUD | HUD 把自己隐藏了:其屏幕控件会添加一个虚拟 Gamepad | 使用 TouchControlsVisibility(跳过 OnScreen 用法) |
| 声明隐私类别 | Unity 为其提供的理由被丢弃(0A2A.1,已观察到) | write_privacy_manifest 会保留并集 |
将 BuildReport.summary.totalSize 作为 Android 大小 | 53.9 MB 的 AAB 显示为 789.8 MB(已观察到) | 使用 aab_facts、bundletool get-size total |
交接
- 接收: 来自 scenario-unity-expert 的场景、预制件和预算;来自 scenario-unity-ui 的 UI 布局(应用安全区域面板和触控 HUD);来自 scenario-unity-shaders 的着色器(变体、深度/不透明纹理的使用);来自 scenario-unity-world-building 和 scenario-textures 的内容(导入策略)。
- 交付: 将分级资源和 URP 发现交给 scenario-unity-rendering-lighting;将性能分析 CSV 和设备捕获请求交给 scenario-unity-performance;将构建任务、密钥库和环境约定交给 scenario-unity-pipeline-automation(CI);将输入绑定交给 scenario-unity-architecture;将 Web 体积或浏览器相关工作交给 scenario-unity-web。交付包:审计 JSON、联系表、
aab_facts和门槛、xcode_facts和门槛、NUnit 总数、已验证和假设事项列表、设备与商店检查清单。
Unity 6.3 说明
- 自 2026-08-31 起,Play 的目标 API 为 36;最低 API 为 25(6.5 中为 26);在 6000.3.17f1+ 中使用 Gradle 9.1.0 / AGP 9.0.0;GameActivity 是默认入口点。6000.3.21f1 的 URP 模板会提供 Target API Automatic、APK 输出和占位包 ID(观察所得):请设置这三项。引擎库已按 16 KB 对齐(观察所得)。
AndroidProjectFilesModifier仅编辑自定义模块:AndroidProjectFiles.UnityLibraryManifest在 6000.3.21f1 中无法编译(观察所得)。LevelPlay 9.5.1 会通过自己的生成后钩子添加 AD_ID(源码所示):更改此设置后请进行干净构建。- 调用
QualitySettings.SetQualityLevel后,GraphicsSettings.currentRenderPipeline在该帧仍会返回之前的资源(观察所得):请读取QualitySettings.renderPipeline。 - App Store 需要 Xcode 26 和 iOS 26 SDK;6.4 会将运行时库移入
UnityRuntime.framework(请重新检查后处理脚本)。PVRTC 已在 6.4 中移除。 - Adaptive Performance 是一项核心功能(
UnityEngine.AdaptivePerformance);自动控制仅适用于 Android 提供程序。 LevelPlay.SetConsent在 9.5.1 中已弃用(改用LevelPlayPrivacySettings);自 2026-01-31 起,com.unity.ads已属于旧版变现方案。
参考资料
references/expert-notes.md:按来源整理的原则,包含时间戳、观察结果和来源分歧之处。references/procedures.md:M1 至 M13 的可复制调用,每项均附实时测试和记录结果。references/critique.md:用于评判预算、分级、资源、UI、构建、资金代码和交接的评分标准。references/gui-paths.md:通过 Unity、Xcode 和商店控制台执行相同任务的路径。references/sources.md:所有来源及其凭据、URL、最佳时间戳和修订历史。