多语言 Localization
把策划维护的 Excel 文案表,在生成期烘焙成 Blob 文件,运行期由静态管理器按 key 取当前语言文本,并驱动 UI 组件自动刷新。
命名空间 HYC.Framework.Loc。一句话:编辑期是 Excel,产物是 StreamingAssets 下的 Blob,运行期只有两个 Dictionary 查表。
全链路
① Excel(.xls/.xlsx,默认 Assets/Localization)
首行 = 表头(必须有 id 列,其余列按语言代码归一化)
↓ HYC Framework/Localization/Import/Excel (Import & Build Blob)(NPOI 读取)
② 产物目录(默认 Assets/StreamingAssets/Localization)
id / cn.lang / en.lang / ... BlobArray<BlobString>
lang / filter / debug_ids / debug_names
↓ 运行期 LocalizationBlobSystem(BeforeSceneLoad)
③ LocalizationManager.Reload(folder)
↓
④ LocalizationManager.GetText(key) → LocalizedBase 组件 / 业务代码
核心类
| 类 / 文件 | 职责 |
|---|---|
Locale | 语言枚举:Default=0 / Chinese=1 / English=2 / Japanese=3 / Korean=4 |
LocaleUtil | 语言代码 ↔ 枚举 ↔ Excel 表头归一化 |
LocalizationManager | 静态管理器:加载、语言切换、查文本 |
LocalizationBlobSystem | SystemBase,开机自动从 StreamingAssets 加载 |
SensitiveWordManager | 敏感词 Trie 过滤(字符串扩展方法) |
LocalizedBase + 三子类 | 挂在文本组件上自动刷新(LocalizedText / LocalizedTMP / LocalizedTextMesh) |
LocalizedTextAttribute / LocKeyAttribute | 标记 string 字段为本地化 key(Inspector 画选择器 + 预览) |
语言代码约定
| Locale | 代码 | Excel 表头可写 |
|---|---|---|
| Default | en | —(兜底) |
| Chinese | cn | 中文 / 简体中文 / 简中 / cn / zh / chs |
| English | en | English / en / us |
| Japanese | jp | 日本語 / 日文 / jp / ja |
| Korean | kr | 한국어 / 韩文 / kr / ko |
◈
繁體中文 / 繁中 / tc / cht 会归一化成 tc——这是一个没有对应 Locale 枚举值的代码,LocaleUtil.FromCode("tc") 会回落到 Default。未知表头原样保留,所以自定义语种也能导,只是枚举认不出来。运行期 API
// 语言
LocalizationManager.SetLanguage(Locale.Chinese);
LocalizationManager.SelectedLanguage = "cn"; // 直接给代码也行
var cur = LocalizationManager.CurrentLocale; // → Locale.Chinese
// 查询
string s = LocalizationManager.GetText("ui/common/confirm");
string f = LocalizationManager.GetText("tip/level_up", 12, "Aria"); // string.Format 占位符
string e = LocalizationManager.GetTextByLang("ui/common/confirm", "en");
bool ok = LocalizationManager.HasKey("ui/common/confirm");
// 扩展方法(等价)
string s2 = "ui/common/confirm".ToLocal();
tmpText.SetKey("ui/common/confirm");
// 切换监听
LocalizationManager.onLanguageChanged += OnLangChanged;
查不到 key 时的表现:key 不存在 → "未找到Key : {key}";key 存在但文本为空 → "[{key 最后一段}]"(如 [confirm]);key 为 null/空 → string.Empty。所以空文案不会静默消失,会显示成 [xxx] 方便定位漏翻。
文本组件
| 组件 | 目标 | 约束 |
|---|---|---|
LocalizedText | UnityEngine.UI.Text | [RequireComponent(typeof(Text))] + [DisallowMultipleComponent] |
LocalizedTMP | TMP_Text | 同上 |
LocalizedTextMesh | TextMesh(3D) | 同上 |
基类 LocalizedBase:Key 字段带 [InspectorName("本地化ID"), LocalizedText],Inspector 里是「文本框 + ▾ 选择器 + ◉ 预览」。OnEnable 订阅 onLanguageChanged,语言切换时自动 Refresh()。代码里动态改:GetComponent<LocalizedTMP>().SetKey("ui/common/confirm");
编辑器入口
| 菜单 | 用途 |
|---|---|
HYC Framework / Localization / Import / Excel (Import & Build Blob) | 导入全部 Excel 并写 Blob、Reload |
HYC Framework / Localization / Settings / Localization Settings | 配 Excel 目录 / 输出目录 / 默认语言 / 敏感词文件 |
HYC Framework / Localization / Editors / Key Browser | 浏览表、按 key 过滤、看每语言文本、导出 CSV |
HYC Framework / Localization / Editors / Sensitive Words | 敏感词过滤测试台 |
常见坑
- 产物必须落在 StreamingAssets 下,否则打包后
LocalizationBlobSystem读不到(它只读Application.streamingAssetsPath/Localization)。 - CJK 文本要靠自定义
AllocateString:Unity 自带的按Length * 2 + 1分配,中文 UTF-8 是 3 字节/字会被截断。LocalizedExcelReader按真实 UTF-8 字节数 + 1 手写分配,不要换回内置方法。 - 真正稳定的是语言代码字符串(
cn/en/jp/kr),跨系统传递用代码,别传枚举数值。 - 编辑器专用的
debug_ids/debug_names只在UNITY_EDITOR下读写,运行时代码不要访问。 GetText(key, args)走string.Format,{0}索引写错会LogException并返回未格式化原文,不会崩。- 切换语言只通知订阅者——自己写的文本(非
LocalizedBase组件)必须挂onLanguageChanged手动刷新。