示例 · 多语言 Loc
运行时用框架同款 API 造最小数据并写到 persistentDataPath → Reload → GetText / SetLanguage / HasKey,导入即跑、不依赖先导出真实 blob。
文件:HYCSimpleLocSampleData.cs(自包含数据生成)/ HYCSimpleLocDemoSystem.cs(运行时查询)
心智模型
- 数据文件(在
StreamingAssets/Localization/或任意文件夹,由Reload(folder)读取):id(键列表,blob)、lang(纯文本默认语言码)、{lang}.lang(每语言一个 blob,文本顺序与id对齐)、filter(可选,敏感词)。 - 运行期:
LocalizationManager.GetText(key)/GetText(key, args)/SetLanguage(Locale)/HasKey(key)。 - 切换语言触发
onLanguageChanged,挂了LocalizedTMP/LocalizedBase的组件自动刷新。
端到端步骤
1. 产出数据 Loc 数据编辑器(Excel → id / lang / *.lang 等 blob)导出到 StreamingAssets/Localization/
2. 加载 LocalizationBlobSystem 在 BeforeSceneLoad 自动加载(内部走 StreamingAssets 抽象,不写平台分支)
3. 代码取文本 string s = LocalizationManager.GetText("ui/start");
string s2 = LocalizationManager.GetText("ui/welcome", name); // {0} 走 string.Format
4. 运行时切换 LocalizationManager.SetLanguage(Locale.Chinese);
5. UI 自动刷新 Prefab 挂 LocalizedTMP,Inspector 设 Key,切语言时自动刷新
⚠
WebGL / Android 上 StreamingAssets 不能直接读文件,自动加载可能早于预取完成而跳过——出包到这两个平台的引导入口必须是
await FrameworkBootstrap.InitializeAsync("World")(先 await StreamingAssets.PreloadAsync() 再建 World)。PC / iOS 上同步/异步入口等价。给 AI 的雷区
id/*.lang都是CfgLocalizationblob(BlobArray<BlobString>),不是纯文本;只有lang是纯文本语言码。手写文件极易错 → 用编辑器导出。- 中文不再截断 + 无需 unsafe:
BlobBuilder.AllocateString在 Unity 2022.3 / Entities 1.0 已是安全 API,且按 UTF-8 真实字节数分配缓冲,CJK(3 字节/字)不再被截断,也不需要工程开/unsafe。 - 文本顺序必须与
id对齐:Reload按数组下标关联,错位会导致 A key 取到 B 文本。 - 找不到 key:
GetText返回"未找到Key : {key}";HasKey可预先判断。 Locale:Locale.Chinese→ 码"cn"(不是"zh");FromCode兼容zh/chs等别名,但文件命名请用规范码。- 🔴
Reload(folder)是「整表替换」,会把宿主的表整艘端走(本 Sample 最惨的一次事故):LocalizationManager是进程级静态单例,一旦成功读到一份有效数据就把整张表换成新目录的。现已改为原子替换(失败只报错并保留原数据),但「成功读到错目录」仍然会端走宿主整张表。
因此本 Sample 立了两条规矩:示例 System 加[DisableAutoCreation];EnsureLoaded()先过CanTakeOver()——全局表非空且不含示例 key 就跳过 Reload 并打警告。
写宿主代码同理:不要在生产路径里无条件Reload全局本地化表。
验证清单
- 前置:新建空场景,把
HYCSimpleSceneBootstrap挂到任一 GameObject 上再 Play。 - 日志依次打出中文「开始游戏 / 欢迎,冒险者!」与英文「Start Game / Welcome, Adventurer!」。
- 故意查一个不存在的 key 应得
未找到Key : xxx。 - 宿主回归:在有自己本地化表的工程里导入本示例、什么都别挂进场景,进 Play —— 宿主 UI 必须一切正常,且 Console 出现「检测到宿主工程已加载自己的本地化数据…跳过 Reload」的黄色警告。