Godot游戏本地化全流程指南:从PO文件到多语言切换
1. 项目概述
如果你正在用Godot开发游戏,并且梦想着你的作品能走出国门,被全球玩家体验,那么本地化就是你绕不开的一环。这不仅仅是把游戏里的文字换成另一种语言那么简单,它涉及到UI适配、文化差异、资源管理等一系列复杂问题。我见过不少独立开发者,项目做到最后,面对多语言支持时要么手忙脚乱,要么干脆放弃,非常可惜。
Godot引擎内置了一套相当成熟的国际化(i18n)和本地化(l10n)系统,其核心就是围绕PO文件(Portable Object)和gettext工具链展开的。这套方案在开源世界和商业软件中久经考验,Godot将其集成进来,让我们能以一种标准化、可维护的方式处理游戏文本。简单来说,PO文件就是一个纯文本文件,里面包含了原文(msgid)和译文(msgmsgstr),配合Godot的tr()函数,就能实现运行时动态切换语言。
这篇文章,我会带你从零开始,彻底搞懂Godot的本地化流程。我们不仅会覆盖从提取文本、翻译PO文件到在游戏中加载和切换语言的完整步骤,还会深入一些官方文档可能没细讲,但在实际项目中一定会遇到的“坑”和最佳实践。比如,如何处理带变量的动态文本、怎么管理图片和音频等资源的本地化版本、UI布局如何应对不同语言的长度差异等等。无论你是刚接触Godot的新手,还是已经做过一两个项目的开发者,相信都能从中找到你需要的东西。
2. 核心概念与工作流解析
在动手之前,我们得先理清几个核心概念和整个工作流,这样后面操作起来才不会迷糊。
2.1 PO文件与gettext:为什么是它们?
Godot的本地化系统深度集成了GNU gettext,这是一个在Linux和开源软件领域极其流行的国际化框架。PO文件是gettext使用的翻译文件格式。选择它有几个显著优势:
- 标准化工具链:有大量成熟工具(如Poedit、Gtranslator)可以编辑、验证和管理PO文件,甚至支持团队协作和翻译记忆库。
- 上下文支持:PO文件允许为相同的原文(msgid)提供不同的译文(msgstr),通过
msgctxt(上下文)字段区分。比如英文的“Close”,在“关闭窗口”和“距离很近”两个上下文中,翻译成中文可能是“关闭”和“接近”。 - 复数处理:很多语言的名词复数形式不止一种(比如俄语、阿拉伯语),gettext原生支持复数形式规则,Godot通过
tr_n()函数完美对接。 - 易于版本管理:PO是纯文本文件,可以很好地用Git等版本控制系统进行管理,方便追踪翻译的修改历史。
与之相对的,Godot也支持CSV格式,这对于从电子表格导入翻译数据很方便,但缺乏上下文和复数处理等高级特性。对于严肃的、需要长期维护的项目,PO文件是更专业的选择。
2.2 Godot本地化核心组件
整个流程涉及Godot引擎的几个关键部分:
Translation和TranslationServer:Translation是一种资源类型,代表一份加载到内存中的翻译字典(比如一个.po或.translation文件)。TranslationServer是全局单例,负责管理所有已加载的Translation资源,并处理当前语言环境的查找逻辑。tr()和tr_n()函数:这是你在代码中获取翻译文本的入口。tr(“KEY”)根据当前语言查找“KEY”对应的翻译。tr_n(“SINGULAR”, “PLURAL”, count)用于处理单复数。- 项目设置中的“本地化”面板:这里是配置翻译资源、资源重映射(如图片、声音)和伪本地化测试的核心区域。
- 编辑器中的“提取可翻译字符串”功能:可以自动扫描项目中的场景、脚本,提取所有需要翻译的字符串,生成PO模板(
.pot)文件。
2.3 完整工作流鸟瞰
一个典型的Godot游戏本地化工作流大致如下:
- 准备阶段:在项目设置中启用并配置本地化。
- 标记文本:在场景和脚本中,对所有需要翻译的文本使用
tr()函数或直接使用翻译键。 - 提取字符串:使用Godot编辑器工具,生成包含所有待翻译字符串的PO模板(
.pot)文件。 - 翻译:将
.pot文件交给翻译人员(或自己),使用Poedit等工具生成针对每种目标语言(如zh_CN.po,ja.po)的PO文件。 - 导入翻译:将翻译好的PO文件导入Godot,它们会被转换为Godot内部使用的
.translation二进制格式(可选,但推荐用于发布),并添加到项目设置中。 - 资源本地化:为不同语言准备不同的图片、字体、音频等资源,并在项目设置中进行重映射配置。
- 运行时切换:在游戏内提供语言选择菜单,调用
TranslationServer.set_locale()来动态切换语言。 - 测试与迭代:使用伪本地化或直接切换语言进行UI测试,确保布局正确、无文本溢出,然后根据反馈更新翻译文件。
接下来,我们就一步步拆解,看看每个环节具体怎么操作,以及有哪些需要注意的细节。
3. 项目基础配置与文本标记
万事开头难,本地化的第一步是正确配置你的Godot项目,并确保所有需要翻译的文本都被正确“标记”出来。
3.1 初始项目设置
打开你的Godot项目,进入项目(Project) > 项目设置(Project Settings)。
- 常规(General)选项卡:
- 找到应用(Application) > 配置(Config)。在这里,你可以设置项目的默认名称。如果你希望应用名称也能被本地化,点击“名称”字段旁边的“可本地化字符串”按钮(一个带“Aa”和地球图标的按钮),然后点击“添加翻译”。这会让你为项目名称添加不同语言的版本。这对于最终打包成可执行文件时,在操作系统菜单或桌面上显示正确名称非常重要。
- 本地化(Localization)选项卡:
- 翻译(Translations):这里目前是空的,我们之后导入的翻译文件会出现在这里。这是告诉Godot“我们有哪些语言包”的地方。
- 重映射(Remaps):用于配置图片、音频等非文本资源的本地化版本。我们稍后再详细讲。
- 区域设置(Locale):
- 测试(Test):一个极其有用的调试功能!你可以在这里填入一个语言代码(如
zh_CN),Godot在运行时会强制使用该语言,无视系统设置。注意:这是一个项目设置,如果你使用版本控制(如Git),记得在提交前清空它,以免影响其他协作者。 - 回退(Fallback):当
TranslationServer找不到当前语言对应的翻译时,会回退到此语言。通常设置为en(英语)。
- 测试(Test):一个极其有用的调试功能!你可以在这里填入一个语言代码(如
提示:对于团队项目,建议将
Test字段留空,并通过版本控制的.gitignore文件忽略对project.godot中此字段的修改,或者使用“覆盖(Override)”功能在本地设置。
3.2 在场景和脚本中标记可翻译文本
这是最核心的一步。你需要告诉Godot,哪些文本是需要翻译的。
对于场景中的控件(Label, Button, CheckBox等):最简单的方式是直接使用翻译键(Translation Key)。在检查器(Inspector)中,将控件的Text属性设置为一个唯一的、描述性的键,例如MAIN_MENU_PLAY、DIALOGUE_NPC_GREETING。当游戏运行时,如果当前语言的翻译文件中存在这个键,Godot会自动用翻译文本替换它。
为什么用键而不是直接写英文?
- 上下文清晰:
UI_SAVE_GAME比“Save”更能让翻译者理解这个文本出现的场景。 - 避免歧义:英文“Close”可以是关闭(动词)也可以是接近(形容词)。用
ACTION_CLOSE和DESCRIPTION_CLOSE作为不同的键可以解决这个问题。 - 便于修改:如果后来想将“Save”改成“Save Game”,你只需要改源语言(如英语)的PO文件,而所有其他语言的翻译键保持不变,不会引起混淆。
在GDScript代码中:使用tr()函数包裹任何需要翻译的字符串。
# 直接使用字符串作为键(不推荐用于复杂项目) $Label.text = tr("Welcome to the game!") # 使用明确的键(推荐) $Label.text = tr("UI_WELCOME_MESSAGE") # 带变量的文本 - 使用格式化字符串,并优先使用命名占位符 var player_name = "Alex" var score = 100 # 方式1:顺序占位符(简单,但翻译时顺序固定) $Label1.text = tr("%s has scored %d points!") % [player_name, score] # 方式2:命名占位符(更灵活,翻译者可调整顺序,强烈推荐!) $Label2.text = tr("{player} has scored {points} points!").format({"player": player_name, "points": score}) # 处理单复数 - 使用 tr_n() var apple_count = 5 $Label3.text = tr_n("You have %d apple.", "You have %d apples.", apple_count) % apple_count # 同样支持命名占位符和上下文 $Label4.text = tr_n("{count} job", "{count} jobs", num_jobs, "Task Manager").format({"count": num_jobs})关于tr()函数的一个关键细节:tr()查找的是翻译后的字符串。如果你像第一个例子那样直接使用英文句子作为键,那么在你的英语PO文件中,msgid是"Welcome to the game!",msgstr也应该是"Welcome to the game!"。对于源语言(通常是英语),翻译文件里原文和译文通常是相同的。很多新手会疑惑为什么英文也要翻译文件,原因就在于此——Godot需要靠这个文件来建立键到文本的映射关系。
3.3 禁用特定节点的自动翻译
有些文本你肯定不希望被翻译,比如玩家输入的名字、服务器地址、内部调试信息等。对于场景中的控件,你可以在检查器中找到自动翻译(Auto Translate)部分,将模式(Mode)设置为禁用(Disabled)。
在代码中,如果你直接给text属性赋值一个字符串,而没有用tr()包裹,它就不会被翻译。所以对于不需要翻译的动态文本,直接赋值即可。
$PlayerNameLabel.text = player_data.name # 玩家名,不翻译 $DebugInfoLabel.text = "FPS: " + str(Engine.get_frames_per_second()) # 调试信息,不翻译4. 提取字符串与生成PO模板
当你把所有需要翻译的文本都标记好后,下一步就是把这些文本收集起来,生成一个给翻译者使用的“任务清单”——PO模板文件(.pot)。
4.1 使用编辑器工具提取
这是最推荐的方法,因为它能自动扫描整个项目。
- 在Godot编辑器中,点击顶部菜单栏的项目(Project)。
- 选择工具(Tools)>提取可翻译字符串(Extract Translatable Strings)...。
- 在弹出的对话框中,你可以选择提取范围:
- 整个项目:扫描所有场景和脚本。
- 当前场景:只扫描当前打开的场景及其子场景。
- 选定的资源:在文件系统面板中选中特定文件后进行提取。
- 点击确定(OK)。Godot会开始分析你的项目,找出所有
tr()调用、场景中设置为翻译键的文本等。 - 分析完成后,会弹出一个窗口,列出所有找到的字符串。你可以在这里进行最后的检查和筛选。
- 确认无误后,点击写入PO模板(Write POT File)...。
- 选择一个保存位置和文件名(例如
translations/game.pot),然后保存。
这个.pot文件是一个纯文本文件,用任何编辑器都能打开。它的内容大致如下:
#: res://scenes/main_menu.tscn::Label.text msgid "MAIN_MENU_PLAY" msgstr "" #: res://scripts/dialogue.gd:42 msgid "DIALOGUE_NPC_GREETING" msgstr "" #: res://scripts/game_ui.gd:15 msgctxt "Achievements" msgid "COMPLETED" msgstr ""每一组msgid和msgstr代表一个翻译单元。#:开头的行注释指明了这个字符串在项目中的位置(文件和行号),这对翻译者和开发者定位上下文非常有帮助。msgctxt用于提供翻译上下文。
4.2 手动维护与自定义提取
对于大型或结构特殊的项目,你可能需要更精细的控制。
- 手动创建/编辑POT:你可以直接用文本编辑器创建或修改
.pot文件。这要求你对PO文件格式非常熟悉。 - 使用
xgettext命令行工具:Godot的提取工具底层可能也使用了类似原理。对于纯脚本项目,你可以用xgettext扫描.gd文件中的tr()调用。但这种方法会漏掉场景中的文本。 - 编写自定义插件:如果上述方法都无法满足需求(比如你的文本存储在外部JSON或数据库中),你可以编写一个EditorPlugin,遍历你的数据源,生成自定义的POT文件。这属于高级用法,需要一定的GDScript编程能力。
实操心得:
- 定期提取:在开发过程中,每当添加或修改了需要翻译的文本,都应该重新提取POT文件,并更新给翻译团队。可以把这个步骤加入到你的构建流程中。
- 版本控制POT:将
.pot文件纳入版本控制。这样你可以清晰地看到哪些字符串是新增的、修改的或删除的。 - 善用上下文(
msgctxt):对于可能引起歧义的短词(如“Menu”, “Back”, “Close”),一定要通过代码(tr(“KEY”, “CONTEXT”))或手动在POT中添加msgctxt来提供上下文。这能极大提高翻译质量。
5. 翻译PO文件与导入Godot
拿到.pot文件后,翻译工作就可以开始了。翻译者不需要接触Godot工程,他们只需要处理PO文件。
5.1 使用翻译工具(以Poedit为例)
Poedit 是一个免费、跨平台、对初学者友好的PO文件编辑器。
- 创建PO文件:在Poedit中,选择文件 > 从POT文件新建翻译目录...,选择你的
game.pot文件。然后选择目标语言,例如“Chinese (China)” ->zh_CN。保存为zh_CN.po。 - 进行翻译:Poedit会列出所有待翻译的条目。选中一条,在下方的翻译框填入对应语言的内容。利用右侧的“源代码位置”可以快速跳转到Godot中查看上下文(如果路径正确)。
- 处理复数:如果原文有复数形式(在POT中会体现),Poedit会为每种复数形式提供单独的输入框。你需要根据目标语言的复数规则填写所有形式。
- 保存:翻译过程中随时保存。Poedit在保存
.po文件的同时,会自动生成一个同名的.mo文件(Machine Object,二进制格式,供程序运行时快速读取)。Godot可以直接使用.po文件,但导入时会将其转换为自己的.translation格式,.mo文件在Godot中不被使用。
5.2 将翻译文件导入Godot
翻译完成后,你需要把.po文件导入到Godot项目中。
- 将
zh_CN.po文件拖放到Godot编辑器的文件系统(FileSystem)面板中,通常放在res://translations/这样的目录下。 - Godot会将其识别为一种可导入资源。在导入(Import)面板中,确保类型(Type)被正确识别为翻译(Translation)。路径(Path)模式保持默认的翻译(Translation)即可。
- 点击重新导入(Reimport)。Godot会在后台将该PO文件编译成优化的
.translation资源(文件扩展名可能是.translation或.tres),这个二进制格式在游戏运行时加载效率更高。 - 添加到项目:光导入还不够,必须让项目“知道”有这个翻译。进入项目设置 > 本地化 > 翻译,点击添加(Add)...按钮,在弹出的文件对话框中,务必选择Godot生成的那个
.translation或.tres文件,而不是原始的.po文件。 - 重复以上步骤,为每种语言(
ja.po,fr.po等)都导入并添加到翻译列表中。
5.3 更新翻译
游戏更新后,有了新的文本,你需要更新翻译文件。
- 重新执行项目 > 工具 > 提取可本地化字符串,生成新的
game.pot。 - 在Poedit中打开已有的
zh_CN.po,选择目录 > 从POT文件更新...,选择新的game.pot。 - Poedit会比对差异,标记出:
- 新条目:需要翻译。
- 过时条目:源文件已删除,翻译被标记为模糊(fuzzy),需要审查。
- 已修改条目:原文变了,翻译被标记为模糊,需要更新。
- 翻译者处理完所有新条目和模糊条目后,保存PO文件。
- 回到Godot,由于原始的
.po文件发生了变化,Godot的导入系统会检测到并自动重新导入,更新对应的.translation资源。你通常不需要在项目设置中重新添加。
注意:Godot的导入系统有时不会立即检测到外部工具对
.po文件的修改。如果你在Godot外部更新了PO文件,回到Godot后,可以在文件系统中右键点击该PO文件,选择重新导入(Reimport)来强制刷新。
6. 运行时语言切换与高级功能
翻译文件准备就绪后,接下来就是在游戏中动态使用它们了。
6.1 设置与切换语言
游戏启动时,通常需要设置一个默认语言。一个好的做法是读取玩家的偏好设置,如果没有,则使用操作系统语言。
extends Node func _ready(): # 1. 先从某个地方(如配置文件)读取玩家保存的语言偏好 var saved_locale = Settings.get_setting("game", "language", "") var locale_to_use if saved_locale != "": locale_to_use = saved_locale else: # 2. 如果没有保存,使用系统语言 var system_locale = OS.get_locale_language() # OS.get_locale_language() 返回的是像 "zh", "en" 这样的语言代码。 # 但我们的翻译文件可能是 "zh_CN", "en_US"。 # 需要做一个简单的映射或检查。 locale_to_use = _map_to_supported_locale(system_locale) # 3. 设置语言 TranslationServer.set_locale(locale_to_use) # 4. 重要:设置语言后,需要手动更新所有已经存在于场景树中的控件的文本! # 因为 tr() 调用发生在 _ready() 之前,文本已经设置好了。 update_ui_text() func _map_to_supported_locale(system_lang: String) -> String: # 假设我们支持的语言列表 var supported = ["en", "zh_CN", "ja", "fr", "es"] # 先检查完全匹配 if system_lang in supported: return system_lang # 检查前缀匹配 (例如 system_lang = "zh_Hans_CN", 我们支持 "zh_CN") for loc in supported: if system_lang.begins_with(loc): return loc # 都不匹配,使用项目设置中的回退语言,或者硬编码一个默认值 return "en" func update_ui_text(): # 这是一个递归函数,遍历场景树,更新所有Label, Button等节点的文本 # 对于简单的UI,可以直接获取节点引用并重新赋值 $MainMenu/TitleLabel.text = tr("UI_GAME_TITLE") $MainMenu/StartButton.text = tr("UI_START_GAME") # ... 更新其他所有需要翻译的控件当玩家在游戏内切换语言时:
func _on_LanguageOptionButton_item_selected(index): var selected_locale = $LanguageOptionButton.get_item_metadata(index) # 假设metadata里存了locale代码 TranslationServer.set_locale(selected_locale) update_ui_text() # 再次更新所有UI文本 # 保存选择到设置 Settings.set_setting("game", "language", selected_locale)6.2 资源重映射:本地化图片、音频等
文字翻译了,但游戏里的图片上如果有文字,或者角色的语音是英文的,怎么办?这就需要资源重映射。
准备资源:为每种语言准备对应的资源文件。例如:
res://assets/ui/title_logo.png(默认/英文)res://assets/ui/title_logo_zh_CN.png(中文)res://assets/voices/welcome.wav(英文语音)res://assets/voices/welcome_ja.wav(日文语音) 命名规范不是强制的,但保持一致性会让管理更轻松。
配置重映射:
- 进入项目设置 > 本地化 > 重映射。
- 点击添加(Add),选择原始资源(如
title_logo.png)。 - 在下方,为每种支持的语言,点击添加重映射(Add Remap),选择对应的本地化资源文件(如
title_logo_zh_CN.png)。 - Godot在运行时,会根据当前语言自动加载重映射后的资源。
注意事项:
- 资源重映射也适用于
AudioStream、FontFile、Theme等任何Godot资源类型。 - 对于字体,如果只是缺少某些语言的字符,更好的方法是使用DynamicFont的回退字体(Fallback)功能,添加一个包含更全字符集的字体(如Noto Sans CJK)作为回退。
6.3 伪本地化:提前发现UI布局问题
德语单词平均比英语长30%,阿拉伯语是从右到左书写……如何确保你的UI能适应各种语言?伪本地化(Pseudo-localization)是一个强大的测试工具。
- 启用:在项目设置 > 本地化 > 区域设置中,勾选启用伪本地化(Enable Pseudo-localization)。
- 配置:你可以调整伪本地化的行为:
- 替换为占位符文本:将所有可翻译文本替换为无意义的占位符(如
[XXX]),快速找出漏翻译的文本。 - 替换为伪本地化文本:这是最常用的模式。它会将原文中的字符替换为外形相似但带重音或变形的字符(如
Hello->[Ĥéłłô]),并可能在首尾添加[ ]。这能模拟文本长度增加和字符扩展的效果。 - 扩展比例:控制文本“变长”的程度,例如设置为150%,让所有伪本地化文本长度变为原来的1.5倍。
- 前缀/后缀:在文本前后添加特定字符,测试UI边界。
- 替换为占位符文本:将所有可翻译文本替换为无意义的占位符(如
启用伪本地化后运行游戏,你会立刻看到UI在“压力测试”下的表现。按钮文字是否超出边界?容器是否被撑开?滚动区域是否足够?在开发早期就进行这项测试,能节省大量后期调整布局的时间。
6.4 处理从右到左(RTL)语言
对于阿拉伯语、希伯来语等RTL语言,Godot提供了自动的UI镜像支持:
- 控件布局:容器(如HBoxContainer)中子控件的顺序会自动反转。
Anchor的左右边也会自动交换。 - 文本对齐:
Label和Button等控件的文本对齐方式(左对齐/右对齐)会自动镜像。 - 文本渲染:文本本身会按照从右到左的顺序正确渲染,包括混合其中的数字和拉丁字母。
大多数情况下你不需要做额外工作。但有一些地方需要注意:
- 自定义绘图:如果你在
_draw()中手动绘制UI元素,需要考虑镜像逻辑。可以通过Control.is_layout_rtl()来判断当前是否是RTL布局。 - 纹理翻转:一些方向性图标(如前进/后退箭头)可能需要水平翻转。可以通过检查
Control.is_layout_rtl()来动态设置TextureRect的flip_h属性。 - 非UI节点:
Sprite2D、Node3D等节点的位置和旋转不会被自动镜像。
7. 常见问题、调试技巧与优化策略
即使按照流程操作,实践中还是会遇到各种问题。这里汇总了一些常见坑点和解决方案。
7.1 翻译不显示或显示为键名
这是最常见的问题。
- 检查1:翻译文件是否已添加到项目设置。光导入
.translation文件不够,必须去项目设置 > 本地化 > 翻译里点击“添加”把它加进去。 - 检查2:当前语言是否匹配。确认
TranslationServer.get_locale()返回的语言代码与你的PO文件名(如zh_CN)匹配。语言代码是大小写敏感的,通常用小写语言代码和用下划线连接的大写地区代码。 - 检查3:键是否完全一致。
tr(“HELLO”)和PO文件里的msgid “HELLO”必须完全一致,包括大小写和空格。 - 检查4:翻译文件是否已加载。可以通过
print(TranslationServer.get_loaded_locales())查看已加载的语言环境列表。 - 检查5:控件是否禁用了自动翻译。确认场景中控件的自动翻译 > 模式不是禁用。
7.2 动态生成的文本翻译
对于在运行时拼接的复杂字符串,直接tr()是没用的。
# 错误做法:tr()只会在运行时查找“Item”和“name”,而不是完整的句子。 var text = tr("Item") + “: “ + item_name + “, “ + tr(“Quantity”) + “: “ + str(count) # 正确做法1:使用完整的、带占位符的翻译键。 var text = tr(“ITEM_DISPLAY_FORMAT”).format({“item_name”: item_name, “quantity”: count}) # 在PO文件中:msgid “ITEM_DISPLAY_FORMAT” | msgstr “物品: {item_name}, 数量: {quantity}” # 正确做法2:如果组合逻辑非常复杂,可以考虑将模板字符串也作为翻译键。 var template = tr(“ITEM_DESCRIPTION_TEMPLATE”) # 例如:“A {quality} {type}” var text = template.format({“quality”: tr(item.quality), “type”: tr(item.type)})7.3 字体与字符显示问题
翻译生效了,但显示出来是乱码或方框(□)。
- 原因1:字体缺失字形。默认的Godot字体(如
DynamicFont使用的默认字体)通常只包含拉丁字母基本集。 - 解决方案:
- 为你的UI主题(Theme)设置一个支持多语言的字体,例如Google的Noto字体家族(Noto Sans, Noto Sans CJK等)。
- 在
Label或Theme的字体设置中,添加回退字体(Fallbacks)。如果主字体缺少某个字符,Godot会尝试从回退字体中查找。 - 对于特定语言(如中文、日文),你可能需要专门下载并导入相应的字体文件,并将其设置为主字体或高优先级的回退字体。
7.4 性能考量与优化
- 二进制格式(.translation):发布游戏时,务必使用Godot导入后生成的
.translation二进制文件,而不是原始的.po文本文件。二进制格式加载更快,内存占用更小。 - 按需加载:如果你的游戏支持非常多语言,可以考虑不要一开始就加载所有语言的翻译文件。而是在玩家切换语言时,动态加载对应的
.translation资源(使用ResourceLoader.load()),并用TranslationServer.add_translation()添加,用TranslationServer.remove_translation()移除不需要的。但要注意管理好资源引用,避免内存泄漏。 - 字符串数量:极端情况下,如果翻译条目数万,查找可能成为瓶颈。Godot内部使用HashMap,效率很高,通常不是问题。但应避免在每帧的
_process中大量调用tr(),尤其是带有复杂格式化的调用。
7.5 与版本控制系统协作
- 应该提交什么?
- 应该提交:
.pot模板文件、所有语言的.po源文件。这些是文本文件,差异对比清晰。 - 不应提交(或忽略):Godot导入生成的
.translation、.tres等二进制资源文件。因为它们可以从.po文件重新生成。在.gitignore中添加*.translation和*.tres(如果你放在特定文件夹,如translations/,则忽略该文件夹下的这些类型)。 - 谨慎提交:
project.godot中的locale/test字段。建议团队约定不提交此字段,或使用override.cfg进行本地覆盖。
- 应该提交:
7.6 调试与日志
- 打印当前语言:
print(“Current locale: ”, TranslationServer.get_locale()) - 列出所有已加载翻译:
print(“Loaded locales: ”, TranslationServer.get_loaded_locales()) - 模拟缺失翻译:临时从项目设置的翻译列表中移除某个语言文件,测试回退机制是否正常工作。
- 使用伪本地化:这是最强大的视觉调试工具,务必善用。
本地化是一个贯穿游戏开发始终的持续性过程,而不是最后一步的“附加任务”。从项目早期就建立规范的本地化流程,使用键而非直接文本,并利用Godot提供的强大工具进行测试,可以让你在面向全球市场时更加从容。希望这篇指南能帮助你扫清障碍,让你的游戏畅通无阻地抵达世界各地的玩家手中。如果在实践中遇到更具体的问题,Godot活跃的社区和详尽的文档永远是你可以依靠的后盾。
