Localization Checker 手册(下):你的工程、Console 和已知的限制
本页目录
本手册说明扫描、Scene 临时预览和 Play 巡检对工程的影响,以及使用前提和已知限制。检查规则和结果解读见 Manual-Checks.zh-Hans.md。
扫描和预览对工程的影响
这里区分三种操作:扫描 在预览副本上应用译文和测量;Scene 临时预览 短暂替换源物体上的文字;Play 巡检 通过游戏本地化系统切换运行时语言。不能将其中一种操作的保证套用于其他操作。
编辑模式扫描
源场景 / Prefab
↓ 复制
隐藏预览场景中的副本
├─ 移除用户脚本
├─ 字体和材质改用内存副本
└─ 清除指向副本外对象的引用
↓ 应用译文,排版并测量
销毁副本
- 场景和 Prefab。 扫描不对源对象记录 Undo、标脏或保存,也不修改 Game 视图的分辨率列表。Prefab 加载、对象复制和扫描后的资产卸载仍有下文所述影响。
- 副本上的代码。 用户脚本在副本激活前移除,事件被禁用,指向副本外对象的引用被清空。复制包含一次序列化往返,构造函数和序列化回调仍可能执行,因此不能理解为所有用户代码都不运行。
- 字体和材质。 TMP 排版可能添加动态字形或写入材质参数。扫描为使用到的字体资产和材质建立内存副本,避免测量直接写入源资产;不写 TMP Settings。这项隔离不适用于游戏正常运行时的字体变化。
- Unity Localization。 扫描只通过只读接口读取数据,不修改 Localization Settings,也不请求已经格式化的本地化字符串。Play 巡检需要读取和设置当前语言。
- 游戏构建。 插件仅在编辑器中运行,不加入游戏构建,也没有用于运行时加载的 Resources 文件夹。
- 设置和结果文件。 工程设置保存在
ProjectSettings/LocalizationChecker.json。界面语言、巡检栏开关、清单列、并排预览选项和上次导出目录保存在编辑器偏好中。扫描结果不写入磁盘;已完成巡检页在当前编辑器会话中保留,截图位于Temp/LocalizationChecker/Patrol。插件不在Assets下创建这些文件,导出也拒绝Assets、Packages或包目录。 - 剪贴板。 插件窗口打开时,每次编辑器获得焦点都会读取一次剪贴板文本,用于识别 HTML 报告 在 Unity 里选中 复制的定位标记。只有点击复制按钮时,插件才会写入剪贴板。
Scene 临时预览会修改当前物体的显示文字。 选中扫描爆框结果后,插件将译文临时写入源文本组件,不记录 Undo、不标脏。选择其他行、离开或关闭窗口、开始扫描、保存或关闭场景、进入 Play、重新编译或退出时,插件恢复原文。并排预览 使用副本渲染,不需要这样替换源文字。
扫描结束后会卸载未使用资产。 无论完成、取消还是失败,插件都会执行与 EditorUtility.UnloadUnusedAssetsImmediate 相同的卸载操作,避免部分本地化工具改写仍驻留内存的 Prefab。脚本对资产作出的未标脏、未保存内存修改可能因此丢失;扫描前请标脏或保存需要保留的资产修改。
加载资产仍遵循 Unity 行为。 加载 Prefab 可能执行脚本构造函数和序列化回调,类似在 Project 中选中它。首次加载 TMP 1.1.0 之前保存的字体或精灵资产时,TMP 可能升级其数据,后续保存可能写入升级结果。扫描数据 则只解析 ScriptableObject 文件文本,不加载资产。
巡检改什么,怎么还原
巡检只在 Play 模式运行。除了插件直接管理的临时状态,切换语言还会触发游戏原有的本地化逻辑。
| 影响对象 | 行为与还原方式 |
|---|---|
| 当前语言 | 停止巡检、退出 Play、重新编译、退出编辑器或异常结束时,尝试通过同一切换器恢复巡检前语言。 |
| 文本内容 | 插件不直接写入译文。TMP 使用游戏已完成的排版;旧版 Text 在插件独立的生成器中重新测量。游戏本地化组件会按语言正常更新文字。 |
| 叠加层 | 在 DontDestroyOnLoad 创建名为 Localization Checker Overlay 的 GameObject,包含不接收射线、用于画框的 Canvas,不挂插件运行时脚本。结束巡检时销毁。游戏代码枚举所有 Canvas 时可能发现它。 |
| 时间缩放 | 冻结游戏时间 将 Time.timeScale 临时设为 0;结束后恢复原值。如果游戏期间主动改写该值,插件不覆盖游戏的新值。 |
| 变量样本 | 临时修改 Unity Localization 全局变量的内存值,不保存资产。关闭开关或结束巡检时恢复;游戏期间主动改写的值不覆盖。 |
| 声明的自定义方法 | 按工程代码执行。如果切换方法写 PlayerPrefs 或设置文件,巡检切换时也会触发写入,恢复语言时再调用一次该方法。 |
| PlayerPrefs | 插件本身不写 PlayerPrefs。若启动选择器含 Unity Localization PlayerPrefLocaleSelector,恢复后该选择器记录原语言。I2 切换不保存语言偏好。自定义方法的副作用由工程负责。 |
| 动态字体资产 | 游戏切换语言可能向动态字体添加字形;巡检不回滚这些变化,后续保存可能写入资产。巡检栏会列出发生变化的字体资产。 |
恢复语言不等于回滚游戏状态或自定义方法的全部副作用。建议在可重复进入的页面巡检,并检查游戏自身的保存逻辑和动态字体变化。
Console
- 普通扫描不输出例行日志。对预览副本排版时,插件抑制 TMP 和 uGUI 的警告,例如副本缺字警告;错误和异常仍显示。
- 无法读取的翻译表在 来源 中说明原因,不另外输出日志。
- 导致扫描停止的原因在窗口中显示为 扫描中止:。
- 设置文件无法读取时,Console 输出一条警告,并使用默认设置。
- TMP 首次加载旧 TextCore 字体时,可能输出“Units Per EM”提示,该提示来自字体升级过程。
- 巡检不输出例行日志。当前编辑器会话保存的巡检页无法读取时,会输出一条警告并丢弃这些页。异常结束时,巡检栏显示 上一次巡检因出错结束: 及原因。
- 游戏运行时自身产生的 TMP 警告仍会显示,巡检不会抑制。
- 命令行扫描将摘要、注记和结论写入 Editor 日志。
扫描默认的前提
- 编辑器当前显示内容是读取起点。 Unity Localization 编辑器预览或
[ExecuteAlways]脚本修改过文字时,扫描会读取修改后的内容。扫描前请清除不需要的预览语言。 - Prefab 以已保存文件为准。 Prefab Mode 中未保存的修改不参与扫描。场景必须至少保存过一次,才能扫描、预览或手动指定 key。
- 扫描期间保持编辑器状态稳定。 不支持在进度条显示时关闭窗口或删除正在检查的物体。取消会在当前步骤结束时生效,本次扫描不产生结果。
- EditorOnly 的处理依范围而异。 场景中排除,Prefab 文件中保留。因此扫描某个 Prefab 文件时,可能报告只在编辑器使用、不会进入游戏的文字。
- 一次扫描只使用一种源语言。
巡检默认的前提
- 快捷键需要插件窗口焦点。 F8 和方向键仅在插件窗口处于前台页签且获得焦点时有效。在 Game 中操作后,请先点击插件窗口;若 F8 被其他快捷键占用,直接点击按钮。
- Game 视图需要可见。 插件窗口与 Game 放在同一组页签时,Game 可能不绘制,导致截图失败;请并排放置。
- 等待帧数必须足够。 除 Unity Localization 的 LocalizeStringEvent 外,插件不会额外等待其他异步更新,只等待设定帧数。若文字更新更晚,结果可能以当前语言名记录上一语言的内容,且无法自动识别。截图仍是旧文字时,请增加等待帧数。
- Play 必须持续推进。 暂停时检查会停住。Unity 6 中,编辑器位于后台且未启用 Run In Background 时也可能停住。保持编辑器在前台,或在进入 Play 前启用该选项。
- 检查期间保持语言和页面稳定。 读取当前语言的方法应返回切换方法接收的代码,不区分大小写。若其他逻辑切换语言,或原有页面根节点消失,巡检会结束并丢弃未完成的当前页;之前完成的页保留。
- 关闭插件窗口不停止巡检。 需要重新打开后点击停止,或退出 Play。
- 域重载可开可关。 关闭时,扫描结果可跨 Play 保留。已完成巡检页可跨脚本域重载保留,直到清空结果或关闭编辑器。
已知的限制
爆框和布局
- 测量隐藏物体时,同一 Canvas 中的隐藏内容会同时显示。互斥页签可能因此相互挤压。打开面板才填内容或调整尺寸的运行时代码不会在预览副本中执行,应通过 Play 巡检检查。
- 用户脚本及会在编辑器运行的相关引擎组件会从副本移除。因此脚本调整的尺寸、字体、子物体,以及运行时生成的列表项等不在静态测量范围内。
- 布局控制尺寸的方向不做普通爆框检查,即使 Force Expand 或弹性空间为文字分配了空间。换行文字按整行长度计算,可能不报告临界状态。
- Screen Space - Camera Canvas 使用扫描时编辑器中配置的相机视口,无法反映后续运行时修改。
- Aspect Ratio Fitter 与 Content Size Fitter 等配置冲突可能使布局无法稳定。相关布局根节点会注明“布局排不稳”。
- 自动字号过小 与组件最大字号比较。如果最大值远大于容器可用字号,所有语言都可能触发。建议将最大值调整为源文在该区域内可用的尺寸。
- 不检查 Grid Layout Group 的格子。输入框被内容挤小、占位物体、刻意越界设计或代码定位面板,均可能需要人工排除。
- 扫描伪本地化只估计长度增加带来的风险,不能替代真实译文检查。
文字重叠
- 扫描使用场景中的位置关系,无法预测运行时代码使哪些文字同时显示、移动或生成。
- 每条文字使用包围所有字符的单个矩形;短末行旁的空白也包含在范围内。扫描不应用遮罩,因此滚出视口的文字仍参与比较。
- 不同 Canvas 的文字不比较。巡检也不比较不同根 Canvas,例如独立 Canvas 弹窗与下层界面。
- 场景中原本重叠的文字对不报告,即使译文使重叠进一步增加。
- 巡检需要在不同时间读取不同语言。会移动的界面可先开启 冻结游戏时间,降低位置变化对比较的影响。
换行禁则
- 日文、中文使用 W3C jlreq、clreq 的严格规则。泰文只能检查音节,未使用词典判断词界,因此未标记断点的提示中可能有正确换行。
- 韩文按词换行检查仅用于扫描:TMP 根据 Use Modern Hangul Line Breaking Rules 配置报告;Unity 6000.3 起逐个检查 UI Toolkit 元素。旧版 Text 已在空格处为韩文换行。
- 扫描和巡检均检查 TMP、旧版 Text 的相关断行规则。Unity 6000.3 起扫描也支持 UI Toolkit,但含富文本标签或转义序列的文字跳过,并在注记中列出数量。巡检不检查 UI Toolkit 的换行禁则。
缺字
- 不检查
<font=…>标签指定内容、样式定义内容、转义字符、Smart String 分支、变量样本和伪译文中的字符。 - 大小写样式使用不依赖区域的规则,不能覆盖土耳其语等特殊大小写。例如设备使用土耳其语时,TMP 可能将
i转为İ。 - 无法读取 I2 第二个 term 或自定义代码的换字体逻辑;请用 按语言换的字体 补充。
- 动态字体按编辑器内当前资产状态检查,不能推断构建时清除动态数据后的状态。
- 团结引擎 Advance Text Processing 使用源字体进行字形处理;插件的逐字符覆盖检查不能完全代表该处理结果。
- 波斯文零宽不连字、非泰文中用于断行的零宽空格,以及图标字体的私用区字符,可能是有意内容,却被列为疑似编码问题。
UI Toolkit(Unity 6)
- 无法识别不带省略号的
overflow: hidden裁切,可能将其报告为撑爆;也不读取祖先元素裁切。 - 重叠使用元素整个矩形,无法按实际字形范围比较。不同文档之间不比较。
- 引擎未公开这些元素的自动字号配置,检查使用排版时可读取的字号。
- 回退字体来自面板 Text Settings,无法读取引擎内置默认 Text Settings。
- 脚本绑定、代码设置的文字和运行时新增元素不参与静态扫描。
占位符、标签和译文
- 没有复数变化的语言移除 Smart String 复数格式后,可能被报告为占位符次数不同。
- 标签指定的字体、精灵和样式,仅在整个工程中不存在同名资产时报告;资产存在但运行时不可访问的情况无法识别。
- 有意使用非拉丁文字的标签值,例如中文样式名,也会按相应规则列为严重,需要结合工程用途判断。
- 和源文相同 可能包含人名、
OK或同语言地区变体。西班牙语、葡萄牙语和加利西亚语的TODO不作为待翻译标记。 - 乱码检查识别 UTF-8 被当作 Windows-1252、Latin-1、GBK、Windows-1250、Windows-1251、Shift-JIS 或 CP949 读取的特征,不覆盖其他代码页。极短乱码可能漏报;GBK 误读后只有一两个生僻字夹在常用字中也可能漏报,但整表误读通常更容易识别。
- 结尾标点、空白、配对符号和数字检查只指出差异。语言习惯、单位换算或刻意文案调整都可能造成合理差异,不能仅凭这些结果判定译文有错。
- 译文可能过长 使用文字单位估计:东亚宽字符计 2,组合标记计 0。它不了解字体和容器。对话、运行时拼接内容应再用巡检测量。
没接入本地化的文字
- 插件无法识别的本地化系统,可能被报告为硬编码;若有脚本字段引用,可能列为 可能由脚本填写。
- key 本身就是英文源文时,文字内容与译文相同,也可能列为硬编码。
- 可能由脚本填写 仅表示存在脚本字段引用;即使脚本只改变颜色也会满足条件。
翻译文件、Unity Localization 和绑定
- CSV、TSV 需要 UTF-8,不支持 GBK。重复 key 会导致整个文件不参与检查。
- TSV 中的引号按文字保留;如果导出工具使用带引号 TSV,请改存 CSV。Google Sheets 的 TSV 会将单元格换行转为空格,需要保留换行时请下载 CSV。
- XLIFF 不将内联代码还原成标签,应在导出时将标签作为普通文本;Unity Localization 使用这种导出方式。
- Excel 读取保存值及公式缓存,不套用数字或日期显示格式。15 位以内整数归一化为整数,例如
100001.0变为100001;日期通常保留为 Excel 序列数,其他数字保留文件写法。需要保持字面内容时,将单元格设为文本并保存。 - PO 的复数形式数量取自
Plural-Forms,不验证其是否为该语言的正确规则。msgid 的语言 留空时,msgid 仅为 key,各语言按相同形式编号与源语言比较;如果源语言形式 0 没有数字(如One apple),而俄语、日语的形式 0 含数字,可能报告多出占位符。文件头只指定形式数量、未提供plural=时,所有形式都要求完整占位符。 - 按
de/LC_MESSAGES/messages.po这类语言文件夹组织的 PO,拖入或从建议添加时,每个文件夹会分别建表。需要合并时,请通过 选择… 将文件添加到同一张表。 - JSON 嵌套路径以点连接,如
menu.start;如果游戏采用其他 key 连接方式,绑定可能显示找不到 key。 - 源语言按表中语言代码匹配,
zh-CN与zh-Hans在此视为不同语言。 - Unity Localization 中,与其他条目重名或 Id 为 0 的条目不读取;Smart String 按原始内容比较。仅读取编辑器 Available Locales 中列出的语言,可通过 Add All 加入其他语言。不在 1.5.2 及以上、2.0 以下范围的包版本,会在 来源 中说明并跳过。
- 手动 key 映射对应具体物体,Prefab 文件与场景实例分别映射。
- 工程外翻译文件在导出中使用完整路径,可能包含本机用户名。
预览、并排预览、热力图、比较
- Scene 临时预览和并排预览只支持已打开、保存过的场景物体,不支持独立 Prefab 文件。Scene 视图使用当前 Game 视图尺寸,未必是问题对应的扫描分辨率。
- 并排预览图片每边最多 8192 像素,未导出时只保存在内存中。
- 热力图仅覆盖 Scene 视图显示的场景。Hierarchy 标记依赖经典 Hierarchy;Unity 6.6 起仅有新 Hierarchy,不显示此标记。
- 扫描比较不持久保存。关闭窗口或脚本重载后,没有旧结果可供比较。表以名称识别,重命名后其问题会视为新出现。
- HTML 的 在 Unity 里选中 要求插件窗口打开,且报告来自当前工程。对于未打开的场景,只高亮场景文件,不自动加载。
巡检
- 满足组件可见条件不保证玩家实际可见。屏幕外、被模板遮罩或其他图形覆盖、被颜色和部分透明度淡化的文字,仍可能参与检查。
- 巡检不检查旧版 Text 的字形覆盖;静态扫描又看不到运行时设置内容,因此这类文字可能两边都漏报缺字。旧版动态字体可借用本机字体,截图表现也不能代表目标设备。
- Dynamic OS 字体使用编辑器电脑上的系统字体。编辑器中缺失的字符不一定在设备上缺失,反之亦然。
- World Space Canvas 既无自己的相机、也无主相机时,无法绘制问题框。
- 运行时生成物体的 id 仅在当次 Play 有效;DontDestroyOnLoad 及从未保存场景中的文字没有稳定 id。这些结果不能取代相应扫描结果,事后也可能无法选中。
- Smart String 格式化、裁剪空白、I2 为中日泰文插入空格或从右往左修正,均可能使游戏字符串与扫描内容不同;即使巡检读到了该文字,扫描爆框仍会继续计数。
- 界面、布局或字体修改后,旧巡检页仍保留。请重新检查对应页,或点击 清空巡检结果。
- 伪语言只按括号判断。玩家名、语言名、代码等故意原样显示的内容可能一直报告,需用适用忽略规则排除。在加括号前已完成的 Smart String 变量或嵌套本地化拼接只算一个片段,无法据此识别内部拼接。
- 如果游戏在同一帧也调用 Unity 截图,两个截图文件可能有一个写入失败。
- 巡检逐帧遍历显示中的文字,会产生额外开销。一个约 1000 条文字的测试场景在测试机上约为每帧 7 到 8 毫秒;此数值仅供参考,实际开销需在目标工程中测量。
- 关闭域重载并连续进入 Play 时,Unity Localization 有时无法完成初始化,这在未安装插件时也可能发生。巡检会拒绝切换语言并说明原因。
I2 Localization
- I2 2.8.22 的接入检查来自测试工程及一个接入 I2 的游戏工程,不能代表所有 I2 项目和版本的完整兼容性。
- 多个语言源对同一 term、同一语言提供不同译文时,该文字在该语言中不测量。
- 扫描会合并范围内文件的语言源;游戏运行时只有同时加载的语言源能相互访问,二者范围可能不同。
- 静态扫描不应用修改译文的回调或事件、中日泰等连写语言间的插入空格、从右往左修正,以及通过第二个 term 切换字体。
编辑器和包
已有兼容性检查覆盖 Unity 2022.3 LTS、Unity 6 的 6000.3 至 6000.6、团结引擎 2022.3(团结 1.5、1.10),以及 TMP 3.0、3.2、uGUI 1.0、2.x 和 Unity Localization 1.5.2 及以上、2.0 以下。它们不代表所有补丁版、字体与工程配置都经过验证。
TMP 3.2.0 的 pre.1、pre.2 预览版存在富文本解析差异,相关随包检查有失败;使用这些预览版时,需要额外核对标签结果。
Play 巡检的验证包括 Unity 2022.3 和 Unity 6 的部分组合:6000.3、接入 I2 的 6000.4、6000.6,以及域重载开关和 Device Simulator。团结 1.5、1.10 仅有有限探针检查,不能等同完整 Play 巡检验收;使用前仍需在目标工程实际走查。
- 未安装 Unity UI(uGUI)时,插件可编译,但没有可用检查入口,菜单不显示。
- 未导入 TMP 必备资源时,含 TMP 文字的 Canvas 跳过测量,结果会说明原因。
- 未安装 Test Framework 时,随包测试不参与编译。
静态扫描不覆盖 Unity 2022.3 和团结引擎的 UI Toolkit、不在 Canvas 下的 UI 文字、代码设置的内容和运行时构建的界面。不在 Canvas 下的 3D TMP 不检查布局、文字重叠,也不提供并排预览。对于运行时内容,请在实际页面使用 Play 巡检,并结合本手册的限制与目标设备检查结果判断。