Localization Checker 手册(下):你的工程、Console 和已知的限制

本页目录
  1. 扫描和预览对工程的影响
  2. 巡检改什么,怎么还原
  3. Console
  4. 扫描默认的前提
  5. 巡检默认的前提
  6. 已知的限制
  7. 爆框和布局
  8. 文字重叠
  9. 换行禁则
  10. 缺字
  11. UI Toolkit(Unity 6)
  12. 占位符、标签和译文
  13. 没接入本地化的文字
  14. 翻译文件、Unity Localization 和绑定
  15. 预览、并排预览、热力图、比较
  16. 巡检
  17. I2 Localization
  18. 编辑器和包

本手册说明扫描、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 巡检,并结合本手册的限制与目标设备检查结果判断。