在小游戏中,可能没那么重视多语言支持。但是想将自己的作品放入国际市场,那么还是需要在本地化(Localization)下功夫的。而 Godot 引擎已经为我们提供了一些 API 和示例[1]。而这篇文章是我在实际操作中,对于官方教程没说明白的补充。

因为自己的项目需要,所以暂时只对文本进行替换。事实上 Godot 内置的本地化功能还包括了游戏资源(语音 / 图片等……)替换。功能非常强大

本教程并没有在游戏 UI 上深究,主要是在怎么实现最简单的多语言切换功能。

成果展示

当用户点击后左下角的旗帜标识,界面中的所有文本将会被切换。包括右下角的版本信息(那是通过代码进行替换的),所以本文会涉及到游戏文本的多语言适配。

游戏以中文界面展示
Game shows in English

准备工作

  • Godot 版本:Godot 4.x (在本教程撰写时,Godot 4.2 是可以操作的,理论上这种基础功能的 API 会一直被沿用,如果有问题,欢迎在 Github 中给出 Issue。我会去更新文章)
  • 一个记录了本游戏所有文本及其对应翻译的 csv 文件,下方会有该 csv 文件的内容要求。
  • UI 素材:我用到了像素风的各国 / 地区国旗。这些文件可以在 亚洲旗帜美洲旗帜 中下载。感谢 lukasfdahl 的贡献。
    • 作者声明及版权信息:Each flag is 16 x 16. The flags is free to use for anything but please credit me for them somewhere.
    • 这些旗帜可以免费用于任何用途,但请在某处给予我署名。

准备所有文件

  1. 我们在项目中的根目录 res:// 下创建一个 localization 目录(可选,这只是为了后续项目中的文件显得有条不紊)
  2. 将下载好的 亚洲旗帜 和 美洲旗帜 拖入到这个文件夹中
  3. 右键 localization 文件夹,然后点击 Open in File Manager 在资源管理器中打开该目录
  4. 新建一个 csv 文件,名字随意,这里我将其命名为 game_text.csv,内容如下
KEYS,en_US,zh_CN
GAME_NAME,My Idle Game,我的挂机游戏
START_GAME,Start Game,开始游戏
SETTING,Settings,设置
EXIT_GAME,Exit Game,退出游戏
NEWS,Update News,游戏公告
DATA_SETTINGS,Data Settings,游戏数据设置
VERSION,Game Versions,游戏版本
DEBUG,Debug,测试版

很乱?没关系,我们将其转换成表格就一目了然了。当然,keys 字段用全大写,两个单词之间的空格用下划线 _ 代替,这么做的用途是可以避免在游戏中重复使用。

KEYS en_US zh_CN
GAME_NAME My Idle Game 我的挂机游戏
START_GAME Start Game 开始游戏
SETTING Settings 设置
EXIT_GAME Exit Game 退出游戏
NEWS Update News 游戏公告
DATA_SETTINGS Data Settings 游戏数据设置
VERSION Game Versions 游戏版本
DEBUG Debug 测试版

这就是翻译文件的内容。当然你也可以加入更多国家 / 地区的文本。如繁体、日文等。可以参考语言(文化)代码与国家地区对照表(最全的各国地区对照表)

  1. 回到 Godot 引擎。这时候系统会自动生成两个(或多个,如果你的语言更多的话)二进制 .translation 文件。如果没有,将 csv 文件 reimport 重新导入就好了。
  2. localization 文件夹中创建两个 Atlas Texture 类型的资源。分别命名为两种语言的标识(自定义),这里我直接用了他俩的名字 zh_CN.tresen_US.tres
  3. 将下载好的国旗集分别调整成对应的切图。

完成上述步骤后,我们的 localization 文件夹应该包含这些文件:

localization 目录文件

界面设计

这里我随意设计了一下界面,可以参考最开始的成品展示,或者通过 UI 知识,自己手动设计一个游戏主菜单。

注意,所有需要进行本地化的文本,它的占位符需要与上面定义 .csv 文件的 KEYS 字段名一致!比如游戏名字的 Label,它的 text = GAME_NAME。然后其他的字符串,如右下角的 VERSION 是多语言占位符。而 V 1.0.0.0 是普通的占位符。

界面设计

左下角是 textureButton,它的 texture 就是刚刚我们创建的 Atlas Texture 旗帜。

然后确保每一个控件(有文本的)他们的 Inspector > Localization > Auto Translate 为勾选状态(默认都是勾选的)

项目设置

Project > Project Settings... > Localization 中,添加文件,将第 5 步创建的 .translation 文件全部添加进来。

项目设置 Localization 标签页

到了这一步,点击项目运行,这时候所有的占位符都会自动替换成英文(默认情况下,游戏语言是 en,所以会自动替换成英文)

语言切换

接下来该为那两颗语言按钮赋能了。将他们俩的 pressed() 信号链接到代码中,这里我将所有主页面代码都放在 title.gd 里。直接上代码

func _on_en_us_pressed() -> void:
TranslationServer.set_locale("en_US")


func _on_zh_cn_pressed() -> void:
TranslationServer.set_locale("zh_CN")

这里其实就是当按钮点击之后,使用 TranslationServer[2]set_locale 方法将项目中的 locale 替换成想要的语言。

通过代码切换文本

这时候可以注意到,游戏界面中右下角的版本号只替换了 Game Version 的值,对游戏中 Debug 和 测试版 的值并没有显示出来。这时需要在代码中加入:

func _update_version_text():
version_text.text = "V." + Global.game_version + ("_" + tr("DEBUG") if Global.is_debug_mode else "")


func _notification(what: int) -> void:
if what == NOTIFICATION_TRANSLATION_CHANGED:
_update_version_text()

啊咧?怎么一下子这么多东西?别急,我们来逐行分析。

  • 首先是 _update_version_text() 函数中的执行逻辑
    • version_text 是界面设计中,用来显示版本号的 label 控件;
    • 我们拼接字符串并赋值给 version_text.text
      • Global.game_version 是我们定义了一个全局的变量(挖个坑,怎么添加全局变量),里面保存了游戏的版本号
      • Global.is_debug_mode 同理。将他俩当作一个变量就好了。这个定义了游戏是否为调试模式。
      • tr("DEBUG") 是调用 tr 函数[3],用来获取某个翻译之后的值。 DEBUG 则是我们在 csv 文件中定义的 KEY
    • 所以整个字符串拼接逻辑是:
      • 拼接 V. 和 游戏版本号。
      • 如果游戏为调试模式(is_debug_mode == true),则再拼接上 _Debug_测试版
  • 再来是 _notification(what: int) 函数:
    • 该函数只有在出发某个 notification 的时候会被调用
    • 判断 what == NOTIFICATION_TRANSLATION_CHANGED,见字知意:当翻译切换时,执行操作
    • 调用 _update_version_text() 来执行更新版本信息的操作。

这时候开始游戏,点击左下角的地区按钮,会看到地区切换了。

修改默认语言(未在发行版本中测试)

最后!我们发现当开启游戏时,默认显示的是英文 (en)。想要调整,很简单,打开 Project > Project Settings... > General 再界面中开启 Advance Settings,然后在左侧找到 Internationalization > Locale > Test。将 Test 的值改为 zh_CN 即可。

项目设置 Internationalization

后记

到这里应该实现了基础的文本 Localization 功能了。如果在实现过程中遇到麻烦,可以直接到 GitHub 上 点击这里 给我 Issue。我会及时进行调整。谢谢您的阅读!祝您开发顺利!

参考资料

[1] Internationalizing games — Godot Engine (stable) documentation in English https://docs.godotengine.org/en/stable/tutorials/i18n/internationalizing_games.html#internationalizing-games

[2] TranslationServer — Godot Engine (stable) documentation in English https://docs.godotengine.org/en/stable/classes/class_translationserver.html

[3] Object — Godot Engine (4.2) documentation in English https://docs.godotengine.org/en/4.2/classes/class_object.html#class-object-method-tr