如何构建适配多语言本地化的复数字符串模板?
适配多语言复数的Roblox本地化方案
核心思路:利用Roblox Translator的ICU复数格式化支持
Roblox的Translator类原生支持ICU格式的复数规则,可以替代手动判断数字区间的方式,自动适配不同语言的复数逻辑(比如法语、西班牙语的复数规则与英语不同),同时减少CSV中的冗余键。
第一步:重构CSV本地化资源
把每个对象的复数形式合并到单个Key下,使用ICU复数语法定义不同基数对应的文本。CSV结构调整如下:
Key, Example, en, fr, es Command.SelectApple, "Select 3 apples", "Select {total, number} {total, plural, one {apple} other {apples}}", "Sélectionnez {total, number} {total, plural, one {pomme} other {pommes}}", "Selecciona {total, number} {total, plural, one {manzana} other {manzanas}}" Command.SelectBanana, "Select 2 bananas", "Select {total, number} {total, plural, one {banana} other {bananas}}", "Sélectionnez {total, number} {total, plural, one {banane} other {bananes}}", "Selecciona {total, number} {total, plural, one {plátano} other {plátanos}}"
说明:ICU复数语法格式为
{变量名, plural, 类别1 {文本1} 类别2 {文本2} ...},常见复数类别包括zero、one、two、few、many、other,不同语言会自动匹配对应类别(比如俄语需要few和many,英语仅需one和other)。
第二步:简化Lua代码逻辑
无需手动判断数字区间,直接通过Translator:FormatByKey传入数字参数,由Roblox自动处理复数匹配:
local LocalizationService = game:GetService("LocalizationService") local LOCALE = "en" local res, translator = pcall(function() return LocalizationService:GetTranslatorForLocaleAsync(LOCALE) end) if not res then warn(string.format("Failed to load the translator with error %s", tostring(translator))) return end local function getSelectionString(numToSelect : number, commandKey : string) assert(numToSelect >= 0, "Cannot select a negative number") return translator:FormatByKey(commandKey, { total = numToSelect }) end -- 测试示例 print(getSelectionString(0, "Command.SelectApple")) -- "Select 0 apples" print(getSelectionString(1, "Command.SelectApple")) -- "Select 1 apple" print(getSelectionString(2, "Command.SelectApple")) -- "Select 2 apples" -- 法语环境测试(修改LOCALE为"fr") -- print(getSelectionString(0, "Command.SelectApple")) -- "Sélectionnez 0 pommes" -- print(getSelectionString(1, "Command.SelectApple")) -- "Sélectionnez 1 pomme"
进阶:复用对象复数模板
如果需要在多个命令中复用同一对象的复数文本,可以将对象的复数定义单独抽成Key,再在命令模板中引用:
重构后的CSV
Key, Example, en, fr, es Object.Apple, "1 apple", "{count, plural, one {apple} other {apples}}", "{count, plural, one {pomme} other {pommes}}", "{count, plural, one {manzana} other {manzanas}}" Command.Select, "Select 3 apples", "Select {total, number} {appleText}", "Sélectionnez {total, number} {appleText}", "Selecciona {total, number} {appleText}"
对应Lua代码
local function getSelectionString(numToSelect : number) assert(numToSelect >= 0, "Cannot select a negative number") -- 先获取对象的复数文本 local appleText = translator:FormatByKey("Object.Apple", { count = numToSelect }) -- 再填充到命令模板 return translator:FormatByKey("Command.Select", { total = numToSelect, appleText = appleText }) end
优势总结
- 无需手动维护数字判断逻辑,自动适配目标语言的复数规则
- 减少CSV中的冗余Key,每个对象/命令仅需一个Key
- 符合本地化最佳实践,支持全球多语言复数场景
内容的提问来源于stack exchange,提问作者Kylaaa
相关产品推荐
相关产品推荐

