Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
游戏的国际化
介绍
虽然独立游戏和小众游戏通常不需要本地化,但瞄准更大市场的游戏往往需要做本地化。Godot 提供了许多工具来简化这一过程,因此本教程更像是一系列技巧和窍门的合集。
本地化通常由专门受雇从事此项工作的工作室完成。尽管有大量软件和文件格式可供选择,但迄今为止最常见的本地化方式仍然是使用电子表格。创建和导入电子表格的过程已在《导入翻译》教程中介绍。如果你之前没有读过导入翻译页面,我们建议你在阅读本页之前先读一下。
备注
我们将使用官方演示作为示例,你可以从资产库下载。
配置导入的翻译
翻译更改时可以更新并重新导入,但它们仍需被添加到项目中。这可以在中完成:
上述对话框用于在整个项目范围内添加或移除翻译。
资源的本地化
还可以指示 Godot 根据当前语言使用资产(资源)的不同版本。这可用于本地化图像(例如游戏内的广告牌)或本地化语音。
重映射选项卡可用于此目的:
选择要重映射的资源,然后为每个语言区域添加一些替代项。
备注
DynamicFont 不支持资源重映射系统。要根据语言文字使用不同的字体,请改用 DynamicFont 回退系统,它允许你根据需要定义任意数量的回退字体。
DynamicFont 回退系统的优点是它无论当前语言如何都能工作,这使其非常适合多人聊天等场景,即文本语言可能与客户端语言不匹配的情况。
自动设置语言
建议默认使用用户的首选语言,可以通过 OS.get_locale_language() 获取。如果你的游戏不支持该语言,则会回退到中的回退,如果为空则回退到 en。不管怎样,出于各种原因(例如翻译质量或玩家偏好),建议让玩家能够在游戏中更改语言。
var language = "automatic"
# Load here language from the user settings file
if language == "automatic":
var preferred_language = OS.get_locale_language()
TranslationServer.set_locale(preferred_language)
else:
TranslationServer.set_locale(language)
区域设置与语言
区域设置通常是语言与国家或地区的组合,但也可能包含文字、变体等信息。
示例:
en:英语语言en_GB:英国英语 / 英式英语en_US:美国英语 / 美式英语en_DE:德国英语
独立游戏通常只需关注语言,但请继续阅读以了解更多信息。
美国和英国的例子可以说明区域设置存在的必要性。两者使用同一种语言(英语),但在许多方面存在差异:
拼写:例如 gray(美国)、grey(英国)
用词:例如 eggplant(美国)、aubergine(英国)
单位或货币:例如英尺/英寸(美国)、米/厘米(英国)
然而情况可能还要复杂。假设你在欧洲和中国提供不同的内容(例如在 MMO 中)。你需要将这些内容变体分别翻译成多种语言,并相应地进行存储和加载。
将键转换为文本
某些控件,例如按钮和标签,如果它们的文本与翻译键匹配,将自动获取翻译。例如,如果标签的文本是 MAIN_SCREEN_GREETING1,并且该键存在于当前翻译中,则文本将被自动翻译。
某些情况下可能不希望出现这种自动翻译。例如,当使用 Label 显示玩家名称时,如果玩家名称与翻译键匹配,你很可能不希望翻译该名称。要禁用特定节点的自动翻译,请在检查器中将Auto Translate > Mode设置为 Disabled。
在代码中,可以使用 Object.tr() 函数。这将仅在翻译中查找文本,如果找到则进行转换:
level.text = tr("LEVEL_5_NAME")
status.text = tr("GAME_STATUS_%d" % status_index)
level.Text = Tr("LEVEL_5_NAME");
status.Text = Tr($"GAME_STATUS_{statusIndex}");
备注
如果更改语言后没有显示任何文本,请尝试使用不同的字体。默认项目字体仅支持 Latin-1 字符集的子集,无法用于显示俄语、中文等语言。
Noto Fonts 是一个不错的多语言字体资源。如果你使用的是不太常见的语言,请确保下载正确的变体。
下载字体后,将 TTF 文件加载到 DynamicFont 资源中,并将其用作 Control 节点的自定义字体。为了更好地重用,请将新的 Theme 资源关联到根 Control 节点,并在主题中将 DynamicFont 定义为默认字体。
占位符
要在翻译字符串中使用占位符,请使用GDScript 格式字符串或 C# 中的等效功能。这使翻译者可以自由移动字符串中占位符的位置,从而使翻译听起来更自然。应尽可能使用 String.format() 函数的命名占位符,因为它还允许翻译者选择占位符出现的顺序:
# The placeholder's locations can be changed, but not their order.
# This will probably not suffice for some target languages.
message.text = tr("%s picked up the %s") % ["Ogre", "Sword"]
# The placeholder's locations and order can be changed.
# Additionally, this form gives more context for translators to work with.
message.text = tr("{character} picked up the {weapon}").format({character = "Ogre", weapon = "Sword"})
翻译上下文
如果你使用普通英文作为源字符串(而不是 LIKE_THIS 这样的消息代码),那么在某些目标语言中将相同的英文字符串翻译为不同的字符串时,可能会遇到歧义。你可以选择指定翻译上下文来解决这种歧义,即使源字符串相同,也允许目标语言使用不同的字符串:
# "Close", as in an action (to close something).
button.set_text(tr("Close", "Actions"))
# "Close", as in a distance (opposite of "far").
distance_label.set_text(tr("Close", "Distance"))
// "Close", as in an action (to close something).
GetNode<Button>("Button").Text = Tr("Close", "Actions");
// "Close", as in a distance (opposite of "far").
GetNode<Label>("Distance").Text = Tr("Close", "Distance");
复数形式
大多数语言根据对象是单数还是复数形式需要不同的字符串。但是,根据对象数量是否大于 1 来硬编码“是否为复数”条件并不适用于所有语言。
某些语言有两种以上的复数形式,并且每种复数形式所需的对象数量规则也各不相同。Godot 提供了对复数形式的支持,以便目标区域设置可以自动处理此问题。
复数形式仅适用于正整数(或零)。负数和浮点值通常表示物理实体,这种情况下单数和复数并不明确适用。
var num_apples = 5
label.text = tr_n("There is %d apple", "There are %d apples", num_apples) % num_apples
int numApples = 5;
GetNode<Label>("Label").Text = string.Format(TrN("There is {0} apple", "There are {0} apples", numApples), numApples);
如有需要,可以与上下文结合使用:
var num_jobs = 1
label.text = tr_n("%d job", "%d jobs", num_jobs, "Task Manager") % num_jobs
int numJobs = 1;
GetNode<Label>("Label").Text = string.Format(TrN("{0} job", "{0} jobs", numJobs, "Task Manager"), numJobs);
使控件可调整大小
不同语言中的相同文本长度可能差异很大。为此,请务必阅读《大小和锚点》教程,因为动态调整控件大小可能会有所帮助。容器 可能很有用,标签 中的文本换行选项也可能会有所帮助。
要检查你的 UI 是否可以容纳比原始字符串更长的翻译,你可以在高级项目设置中启用伪本地化。这将把你所有可本地化的字符串替换为更长的版本,同时还将原始字符串中的某些字符替换为带重音符号的版本(但仍然可读)。占位符保持原样,以便在启用伪本地化时它们继续工作。
例如,当启用伪本地化时,字符串 Hello world, this is %s! 会变为 [Ĥéłłô ŵôŕłd́, ŧh̀íš íš %s!]。
虽然乍一看很奇怪,但伪本地化有几个好处:
它可以让你快速发现不可本地化的字符串,这样你就可以检查它们并使它们可本地化(如果这样做有意义的话)。
它可以让你检查无法容纳长字符串的 UI 元素。许多语言的翻译会比源文本长得多,因此确保你的 UI 能够容纳比平时更长的字符串非常重要。
它可以让你检查你的字体是否包含支持各种语言所需的所有字符。然而,由于伪本地化的目标是保持原始字符串的可读性,因此它并不能有效检查字体是否支持 CJK(中文、日文、韩文) 或从右到左语言。
项目设置允许你调整伪本地化行为,以便你可以根据需要禁用其中的某些部分。
TranslationServer
Godot 有一个负责底层翻译管理的服务器,称为 TranslationServer。可以在运行时添加或删除翻译;当前语言也可以在运行时更改。
双向文本和 UI 镜像
阿拉伯语和希伯来语是从右到左书写的(除了混合其中的数字和拉丁单词),这些语言的用户界面也应该被镜像。在某些语言中,字形的形状会根据周围的字符而变化。
对双向书写系统和 UI 镜像的支持是透明的,你通常不需要更改任何内容或了解特定的书写系统。
对于 RTL(从右到左)语言,Godot 将自动对 UI 进行以下更改:
镜像左右锚点和边距。
交换左右文本对齐方式。
镜像容器中子控件的水平顺序以及 Tree/ItemList 控件中的项目。
使用内部控件元素的镜像顺序(例如 OptionButton 下拉按钮、CheckBox/CheckButton 对齐方式、列表列顺序、TreeItem 图标和连接线对齐方式)。在某些情况下,镜像控件使用单独的主题样式。
坐标系不会被镜像。
非 UI 节点(精灵等)不会受到影响。
可以使用以下控件属性来覆盖文本和控件布局方向:
text_direction,设置基础文本方向。当设置为“auto”时,方向取决于文本中根据 Unicode 双向算法的第一个强方向字符。language,覆盖当前项目区域设置。structured_text_bidi_override属性和_structured_text_parser回调,可以对结构化文本进行特殊处理。layout_direction,覆盖控件镜像。
参见
你可以使用 BiDI 和字体功能演示项目来查看从右到左排版的实际工作方式。
将分词迭代器数据添加到导出的项目中
某些语言书写时没有空格。在这些语言中,分词和换行需要的不仅仅是基于字符序列的规则。Godot 包含基于 ICU 规则和字典的分词迭代器数据,但默认情况下这些数据不包含在导出的项目中。
要包含这些数据,请转到,启用包括文本服务器数据,然后导出项目。分词迭代器数据的大小约为 4 MB。
结构化文本 BiDi 覆盖
Unicode BiDi 算法设计用于处理自然文本,它无法处理具有更高级别顺序的文本,例如文件名、URI、电子邮件地址、正则表达式或源代码。
例如,所示目录结构的路径将无法正确显示(顶部的“LineEdit”控件)。“文件”类型的结构化文本覆盖会将文本拆分为段,然后对每个段分别应用 BiDi 算法以正确显示任何语言的目录名称并保留文件夹的正确顺序(底部的“LineEdit”控件)。
自定义回调提供了一种为其他类型的结构化文本覆盖 BiDi 的方法。
数字的本地化
专门设计用于输入或输出数字的控件(例如 ProgressBar、SpinBox)将自动使用本地化的数字系统,对于其他控件,可以使用 TextServer.format_number(string, language) 将西方阿拉伯数字(0..9)转换为本地化的数字系统,并使用 TextServer.parse_number(string, language) 将其转换回来。
图标和图像的本地化
阿拉伯语和希伯来语区域设置中,带有左右指向箭头的图标如果指示移动或方向(例如后退/前进按钮),则可能需要反转。否则它们可以保持不变。
测试翻译
你可能想要在发布前测试项目的翻译。Godot 为此提供了三种方法。
第一,在下(启用高级设置后)有一个测试属性。将此属性设置为你想要测试的语言的区域设置代码。当项目运行时(无论是从编辑器运行还是导出后运行),Godot 将使用该区域设置运行项目。
请记住,由于这是一个项目设置,当设置为非空值时,它会显示在版本控制中。因此,在将更改提交到版本控制之前,应将其设置回空值。
第二,在编辑器中,转到顶部工具栏并点击,然后向下转到预览翻译并选择你想要预览的语言。
编辑器场景中的所有文本现在都会以所选语言显示。
第三,还可以从命令行运行 Godot 来测试翻译。例如,要使用法语测试游戏,可以提供以下参数:
godot --language fr
翻译项目名称
项目名称在导出到不同操作系统和平台时会成为应用名称。要以多种语言指定项目名称,请转到。在这里,点击按钮,然后点击按钮。这将把你带到一个页面,你可以在其中为项目名称翻译选择语言(以及如果需要,选择国家)。完成后,你就可以输入本地化的名称。
如果你不确定要使用的语言代码,请参阅区域设置代码列表。