使用 gettext 进行本地化
除了 CSV 格式的导入翻译之外,Godot 还支持加载以 GNU gettext 格式编写的翻译文件(基于文本的 .po,自 Godot 4.0 起还支持编译后的 .mo)。
备注
有关 gettext 的介绍,请查看快速 Gettext 教程。它是针对 C 项目编写的,但其中许多建议也适用于 Godot(xgettext除外)。
优势
缺点
gettext 是一种比 CSV 更复杂的格式,对于刚接触软件本地化的人来说可能更难掌握。
维护本地化文件的人员必须在其系统上安装 gettext 工具。但是,由于 Godot 支持使用基于文本的消息文件(
.po),翻译人员无需安装 gettext 工具即可测试他们的工作。
安装 gettext 工具
命令行 gettext 工具是执行维护操作(例如更新消息文件)所必需的。因此,强烈建议安装它们。
创建 PO 模板
使用编辑器自动生成
自 Godot 4.0 以来,编辑器可以从指定的场景和 GDScript 文件中自动生成 PO 模板。如果在脚本中使用,此 POT 生成还支持翻译上下文和复数形式,使用 tr() 和 tr_n() 方法的可选的第二个实参。
打开项目设置的本地化 > POT 生成选项卡,然后使用添加... 按钮指定项目中包含可本地化字符串的场景和脚本的路径:
在项目设置的本地化 > POT 生成选项卡中创建 PO 模板
添加至少一个场景或脚本后,点击右上角的生成 POT,然后指定输出文件的路径。该文件可以放在项目目录中的任何位置,但建议将其保存在子目录如 locale中,因为每个区域都将在其自己的文件中定义。
请参阅下文了解如何添加面向翻译者的注释,以及如何从 GDScript 文件的 PO 模板中排除某些字符串。
然后就可以转到《从 PO 模板创建消息文件》。
备注
请记住,在对可本地化的字符串进行任何更改或新增新场景或脚本后重新生成 PO 模板。否则,新添加的字符串将不可本地化,并且翻译人员将无法更新过时字符串的翻译。
手动创建
如果该自动生成的方法不能满足你的需求,你可以在文本编辑器中手动创建 PO 模板。该文件可以放在项目目录中的任何位置,但建议将其保存在子目录中,因为每个区域设置都将在其自己的文件中定义。
在项目目录中创建一个名为 locale 的目录。在该目录中,保存一个名为 messages.pot 的文件,其内容如下:
# Don't remove the two lines below, they're required for gettext to work correctly.
msgid ""
msgstr ""
# Example of a regular string.
msgid "Hello world!"
msgstr ""
# Example of a string with pluralization.
msgid "There is %d apple."
msgid_plural "There are %d apples."
msgstr[0] ""
msgstr[1] ""
# Example of a string with a translation context.
msgctxt "Actions"
msgid "Close"
msgstr ""
gettext 中的消息由 msgid 和 msgstr 对组成。msgid 为源字符串(一般为英文),msgstr 为翻译后的字符串。
警告
PO 模板文件(.pot)中的 msgstr 值应始终为空。本地化会在生成的 .po 文件中进行。
从 PO 模板创建消息文件
msginit 命令用于将 PO 模板转换为消息文件。例如,要创建法语本地化文件,请在 locale 目录中使用以下命令:
msginit --no-translator --input=messages.pot --locale=fr
上面的命令会在 PO 模板所在的目录下创建一个名为 fr.po 的文件。
你也可以使用 Poedit 以图形方式完成此操作,或者通过将 POT 文件上传到你选择的 Web 平台。
在 Godot 中加载消息文件
如果要将消息文件注册为项目的翻译,请打开项目设置,然后进入本地化选项卡。在翻译中单击添加...,然后在文件对话框中选择该 .po 或者 .mo 文件。区域设置将从消息文件的 "Language: <code>\n" 属性中推断出来。
备注
关于在 Godot 中导入和测试翻译的更多信息,请参阅《游戏的国际化》。
按照 PO 模板更新消息文件
更新 PO 模板后,你必须更新消息文件以使其包含新字符串,同时删除已经在 PO 模板中不复存在的字符串。这可以使用 msgmerge 工具自动完成:
# The order matters: specify the message file *then* the PO template!
msgmerge --update --backup=none fr.po messages.pot
如果你想保留原始消息文件的备份(在本例中会保存为 fr.po~),请删除 --backup=none 参数。
备注
运行 msgmerge 后,在 .po 文件中,源语言中修改过的字符串的前面会添加一条“fuzzy”注释。该注释表示翻译应更新以匹配新的源字符串,因为翻译在更新之前很可能是不准确的。
在翻译更新并删除“fuzzy”注释之前,Godot 不会读取带有“fuzzy”注释的字符串。
检查 PO 文件或模板的有效性
可以通过运行以下命令来检查 gettext 文件的语法是否有效:
msgfmt fr.po --check
如果有语法错误或警告就会显示在控制台中。否则 msgfmt 不会输出任何内容。
使用二进制 MO 文件(仅适用于大型项目)
大型项目会有成千上万的字符串要翻译,相比于基于文本的 PO 文件,使用(编译为)二进制的 MO 消息文件可能更加划算。二进制 MO 文件比对应的 PO 文件更小、读起来更快。
可以使用以下命令生成 MO 文件:
msgfmt fr.po --no-hash -o fr.mo
如果该 PO 文件有效,该命令将在 PO 文件旁边创建一个 fr.mo 文件。该 MO 文件然后可以按照上述方法在 Godot 中加载。
原始 PO 文件应保留在版本控制中,以便你将来更新翻译。如果你丢失了原始 PO 文件,并希望将 MO 文件反编译为基于文本的 PO 文件,你可以这样做:
msgunfmt fr.mo > fr.po
反编译出的文件不包含注释和模糊字符串,因为它们一开始就没有编译进 MO 文件里。
从 GDScript 文件中提取可本地化的字符串
内置的编辑器插件能够识别源代码中的多种模式,可以从 GDScript 文件中提取可本地化的字符串,包括但不限于以下内容:
对
tr()、tr_n()、atr()、atr_n()的调用;为
text、placeholder_text、tooltip_text等属性赋值;对
add_tab()、add_item()、set_tab_title()等函数的调用;FileDialog的过滤器格式如"*.png ; PNG 图像"。
备注
参数和右操作数必须为字符串常量,否则插件无法对表达式求值,会将其忽略。
如果插件提取了不必要的字符串,你可以使用 NO_TRANSLATE 注释来忽略。你也可以使用 TRANSLATORS: 注释为翻译人员提供额外信息。这些注释必须放在与识别模式相同的行上,或者放在前一行。
$CharacterName.text = "???" # NO_TRANSLATE
# NO_TRANSLATE: Language name.
$TabContainer.set_tab_title(0, "Python")
item.text = "Tool" # TRANSLATORS: Up to 10 characters.
# TRANSLATORS: This is a reference to Lewis Carroll's poem "Jabberwocky",
# make sure to keep this as it is important to the plot.
say(tr("He took his vorpal sword in hand. The end?"))