Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

使游戏国际化

前言

Sería excelente que el mundo hablara solo un idioma(如果全世界都讲同一种语言就太好了)。不幸的是对于我们的开发人员来说,情况并非如此。虽然独立或投机游戏通常不需要本地化,但瞄准更大市场的游戏通常需要本地化。Godot 提供了许多工具来使这个过程更加简单,因此本教程更像一个妙招和技巧的合集。

Localization is usually done by specific studios hired for the job. Despite the huge amount of software and file formats available for this, the most common way to do localization to this day is still with spreadsheets. The process of creating the spreadsheets and importing them is already covered in the 导入翻译 tutorial. If you haven't read the Importing translations page before, we recommend you give it a read before reading this page.

备注

我们将使用官方演示作为示例,你可以从资产库下载

配置导入的译文

翻译可以在更改时得到更新和重新导入,但仍必须添加到项目中。可通过项目 → 项目设置 → 本地化来完成:

../../_images/localization_dialog.png

上述对话框用于添加或删除项目范围内的翻译。

资源的本地化

根据当前语言,还可以指示 Godot 使用替代版本的资产(资源)。重定向选项卡可用于此。

The Remaps tab can be used for this:

../../_images/localization_remaps.png

Select the resource to be remapped then add some alternatives for each locale.

备注

The resource remapping system isn't supported for DynamicFonts. To use different fonts depending on the language's script, use the DynamicFont fallback system instead, which lets you define as many fallback fonts as you want.

The upside of the DynamicFont fallback system is that it works regardless of the current language, making it ideal for things like multiplayer chat where the text language may not match the client's language.

将键转换为文本

一些控件,例如 ButtonLabel,如果它们的文本与一个翻译键值相匹配,将自动获取翻译内容。例如,如果一个标签的文本是“MAIN_SCREEN_GREETING1”并且该键值存在于当前的翻译中,那么该文本将被自动翻译。

这种自动翻译行为在某些情况下可能是不可取的。例如,当使用 Label 来显示玩家的名字时,如果玩家的名字与翻译键相匹配,你很可能不希望进行翻译。要禁用某个节点的自动翻译,请在检查器中禁用Localization > Auto Translate(本地化 > 自动翻译)。

在代码中, 可以使用 Object.tr() 函数. 这将只是在翻译中查找文本, 如果找到的话就进行转换:

level.text = tr("LEVEL_5_NAME")
status.text = tr("GAME_STATUS_%d" % status_index)

备注

如果更改语言后不显示任何文字,请尝试换一个字体。默认项目字体仅支持 Latin-1 字符集的子集,无法用于显示俄语、汉语等文字。

A good resource for multilingual fonts is Noto Fonts. Make sure to download the correct variation if you're using a less common language.

Once you've downloaded the font, load the TTF file into a DynamicFont resource and use it as a custom font of your Control node. For better reusability, associate a new a Theme resource to your root Control node and define the DynamicFont as the Default Font in the theme.

Placeholders

若要在翻译的字符串中使用占位符,请使用 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"))

复数

很多语言会根据对象的单复数使用不同的字符串。但是把“是否为复数”的条件硬编码为“对象数量是否大于 1 ”并不是对所有语言都有效。

有些语言有两种以上的复数形式,不同的复数需要的对象数量也各不相同。Godot 提供了对复数的支持,目标地区可以自动进行处理。

复数应该只用于正整数(或零)的情况。负数和浮点数所代表的物理实体数量是单数还是复数一般无法明确区分。

var num_apples = 5
label.text = tr_n("There is %d apple", "There are %d apples", num_apples) % num_apples

如果有需要也可以和上下文组合使用:

var num_jobs = 1
label.text = tr_n("%d job", "%d jobs", num_jobs, "Task Manager") % num_jobs

备注

提供复数翻译仅支持 使用 gettext 进行本地化,不支持 CSV。

使控件的大小可调

不同语言的相同文本的长度差异很大。为此,请务必阅读教程 大小和锚点,因为动态调整控件大小可能有所帮助。Container 可能很有用,Label 的文本换行选项应该也能帮上忙。

To check whether your UI can accommodate translations with longer strings than the original, you can enable pseudolocalization in the advanced Project Settings. This will replace all your localizable strings with longer versions of themselves, while also replacing some characters in the original strings with accented versions (while still being readable). Placeholders are kept as-is, so that they keep working when pseudolocalization is enabled.

For example, the string Hello world, this is %s! becomes [Ĥéłłô ŵôŕłd́, ŧh̀íš íš %s!] when pseudolocalization is enabled.

虽然第一眼看上去很奇怪,但是伪本地化的好处有很多:

  • It lets you spot non-localizable strings quickly, so you can go over them and make them localizable (if it makes sense to do so).

  • It lets you check UI elements that can't fit long strings. Many languages will feature much longer translations than the source text, so it's important to ensure your UI can accommodate longer-than-usual strings.

  • It lets you check whether your font contains all the characters required to support various languages. However, since the goal of pseudolocalization is to keep the original strings readable, it's not an effective test for checking whether a font can support CJK or right-to-left languages.

The project settings allow you to tune pseudolocalization behavior, so that you can disable parts of it if desired.

TranslationServer

Godot 有一个进行底层翻译管理的服务器,名为 TranslationServer。可以在运行时添加或删除翻译;当前语言也可以在运行时更改。

双向文本和 UI 镜像

Arabic and Hebrew are written from right to left (except for the numbers and Latin words mixed in), and the user interface for these languages should be mirrored as well. In some languages the shape of a glyph changes depending on the surrounding characters.

Support for bidirectional writing systems and UI mirroring is transparent, you don't usually need to change anything or have any knowledge of the specific writing system.

对于 RTL(从右至左)语言,Godot 会自动对 UI 进行以下调整:

  • 镜像左右锚点和边距。

  • 交换文本的左对齐和右对齐。

  • 镜像容器中子控件的水平顺序以及 Tree/ItemList 控件中项目的水平顺序。

  • 控件内部元素使用镜像顺序(例如 OptionButton 的下拉按钮、单选框的位置、列表框列的顺序、Tree 项目的图标和连接线的位置等),某些镜像的控件会使用单独的主题样式。

  • 坐标系不会镜像,非 UI 节点(精灵等)不受影响。

It is possible to override text and control layout direction by using the following control properties:

  • text_direction, sets the base text direction. When set to "auto", direction depends on the first strong directional character in the text according to the Unicode Bidirectional Algorithm,

  • language, overrides current project locale.

  • structured_text_bidi_override property and _structured_text_parser callback, enables special handling for structured text.

  • layout_direction, overrides control mirroring.

../../_images/ui_mirror.png

参见

You can see how right-to-left typesetting works in action using the BiDI and Font Features demo project.

在导出后的项目中添加分词迭代器数据

Some languages are written without spaces, and word and line breaking requires more than rules over character sequences. Godot includes ICU rule and dictionary based, break iterator data, but this data is not included into exported projects by default. To include it go to Project → Project Settings → Localization → Text Server Data and click Install support data.... Break iterator data is about 4 MB large.

../../_images/icu_data.png

结构化文本 BiDi 覆盖

Unicode BiDi algorithm is designed to work with natural text and it's incapable of handling text with the higher level order, like file names, URIs, email addresses, regular expressions or source code.

../../_images/bidi_override.png

For example, the path for this shown directory structure will be displayed incorrectly (top "LineEdit" control). "File" type structured text override splits text into segments, then BiDi algorithm is applied to each of them individually to correctly display directory names in any language and preserve correct order of the folders (bottom "LineEdit" control).

Custom callbacks provide a way to override BiDi for the other types of structured text.

数字的本地化

Controls specifically designed for number input or output (e.g. ProgressBar, SpinBox) will use localized numbering system automatically, for the other control TextServer.format_number(string, language) can be used to convert Western Arabic numbers (0..9) to the localized numbering system and TextServer.parse_number(string, language) to convert it back.

图标和图像的本地化

Icons with left and right pointing arrows which may need to be reversed for Arabic and Hebrew locales, in case they indicate movement or direction (e.g. back/forward buttons). Otherwise, they can remain the same.

测试翻译

你可能会想要在发布前测试项目的翻译。Godot 为此提供了两种方法。

First, in the Project Settings, under Internationalization > Locale (with advanced settings enabled), there is a Test property. Set this property to the locale code of the language you want to test. Godot will run the project with that locale when the project is run (either from the editor or when exported).

../../_images/locale_test.webp

请记住,因为这是一个项目设置,设为非空时会在版本控制中显示。因此,将修改提交到版本控制之前,应该将其设回空值。

Translations can also be tested when running Godot from the command line. For example, to test a game in French, the following argument can be supplied:

godot --language fr

翻译项目名称

导出到不同的操作系统和平台时,项目名称将成为应用程序名称。要以多种语言指定项目名称,请在项目设置中创建一个新设置 application/name,并将区域标识符附加到其中。例如,对于西班牙语,这将是 application/name_es

../../_images/localized_name.png

如果你不确定要使用的语言代码,请参阅区域代码列表