跳转到内容

本地化

为每个 locale 注册一份翻译目录(catalog),切换当前 locale,并用 t() 查字符串——都通过 Localization 资源完成。它刻意不依赖 Intl,所以在 Web 与微信上行为一致。

Localization 是**可选(opt-in)**的——在任何系统读 Res(Localization) 之前先装一次它的插件:

import { App, localizationPlugin, LocalizationPlugin } from 'esengine';
app.addPlugin(localizationPlugin);
// …或提前预载目录 + 设置初始/回退 locale:
app.addPlugin(new LocalizationPlugin({
locale: 'en',
fallback: 'en',
catalogs: { en: { play: 'Play' }, 'zh-CN': { play: '开始' } },
}));
import { defineSystem, Res, Localization } from 'esengine';
const setupI18n = defineSystem([Res(Localization)], (i18n) => {
i18n.addCatalog('en', { play: 'Play', score: 'Score: {n}' });
i18n.addCatalog('zh-CN', { play: '开始', score: '得分:{n}' });
i18n.setLocale('zh-CN');
const label = i18n.t('score', { n: 42 }); // "得分:42"
});
  • addCatalog(locale, entries) 把 key 合并进某个 locale——可多次调用追加(后面的会覆盖)。
  • t(key, params?) 会插值 {placeholder} 的值。缺失的 key 回退到 fallback locale,再回退 到 key 本身(一个可见、可 grep 的兜底)。

目录条目可以携带复数形式——CLDR 全集 zero / one / two / few / many / other; t 会根据 count 参数选出一个(且 count === 0 时若有 zero 形式总是它胜出)。默认选择器 是英语式(one/other);斯拉夫语 / 阿拉伯语等规则用 setPluralSelector(locale, (count) => category) 注册,返回上述六个类别之一。

i18n.addCatalog('en', { apples: { one: '{count} apple', other: '{count} apples' } });
i18n.t('apples', { count: 3 }); // "3 apples"
方法 说明
addCatalog(locale, entries) 把翻译 key 合并进某个 locale。
t(key, params?) 查找 + 插值一个字符串。
setLocale(locale) 设置当前 locale。
setFallbackLocale(locale) 设置 key 缺失时使用的 locale。
setPluralSelector(locale, selector) 为某 locale 设自定义复数规则。
availableLocales() 列出已注册的 locale。
has(key) key 是否存在于当前/回退 locale。

检视器里的 .eslocale 字符串表——key 与它们的值

检视器里的 .eslocale 表:每个 key 在当前语言下的值,下方以另一种语言作为翻译提示。

翻译可以作为数据发布,而不是写死在代码里:一个 .eslocale 资产装着一种语言的目录, 游戏只加载它需要的语言。

// assets/i18n/zh-CN.eslocale
{
"version": 1,
"locale": "zh-CN",
"entries": {
"ui.title": "UI 控件",
"apples": { "other": "{count} 个苹果" }
}
}

在编辑器里创建(内容浏览器 → 右键 → 新建本地化表)或手写皆可。选中一张表,细节面板 就是它的编辑器:键/译文行(支持复数形式)、其他表的参照译文淡显在每行下方、缺失的 key 一键补齐——每次编辑立即保存。显式加载用 Assets.loadLocaleTable(path)(需要本地化插件——否则大声报错),预载用 new LocalizationPlugin({ tables: ['assets/i18n/zh-CN.eslocale'] }),或者让 下面的 Text 绑定全自动加载。导出 cook 永远会把 .eslocale 打进包里——它们按 key 加载,可达性分析看不见它们,所以强制收入。

设置 Text.i18nKey(编辑器细节面板里的 I18n Key 下拉,列出项目全部表里的 key 及其 译文预览),content 就变成派生值:每帧重新解析,所以 setLocale——或者一张晚到的 表——都会让所有绑定的标签自动重排,零代码。场景驱动的项目免费得到整条链路:只要场景里 有任何绑定的 key,加载时会自动安装插件、加载全部已发布的表,并在有匹配的表时以 玩家的系统语言启动(自己安装插件、或调用过 setLocale 的游戏永远不会被覆盖)。

动态标签(Score: 42)请保持代码驱动——绑定的 content 是派生的,代码会改写的标签 不能同时携带 key;在拥有它的系统里调 t('score', { n }) 即可。

  • 一切都经 t()i18nKey——绝不硬编码面向用户的字符串,连占位符也不。
  • 插值,别拼接('Score: {n}'),这样语序能因语言而异。
  • 设一个回退 locale,让缺失的翻译退化到另一种语言,而不是裸 key。
  • 一种语言一个 .eslocale,放在同一目录(assets/i18n/),key 完全一致——缺失的 key 会以 key 字符串可见地兜底。
  • UI —— 绑定所依托的 Text 组件。
  • 资源 —— 资产如何发布与加载。