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 提供了許多工具,讓這個流程更加簡單,因此這份教學更像是匯集了一些實用的小技巧和建議。
當地語系化通常是通過雇傭特定的工作室來完成的,儘管有大量的軟體和檔案格式可供使用,但迄今為止進行當地語系化最常見的方式仍然是使用試算表。建立試算表並匯入試算表的過程已經在 匯入翻譯 教學中介紹過了,所以這個教學更像是對那個教學的後續。
備註
我們將以官方範例專案作為示範,你可以從「資源庫」下載:Asset Library。
配置匯入的譯文
Translations can get updated and re-imported when they change, but they still have to be added to the project. This is done in :
上述對話方塊用於新增或刪除專案範圍內的翻譯。
資源的當地語系化
也可以指示 Godot 使用資產 (資源) 的替代版本,根據目前的語言。這可用於本地化影像,例如遊戲內的看板或本地化語音。
The Remaps tab can be used for this:
選擇需要重定向的資源,並指定它在其他語言地區的替代方案。
備註
DynamicFonts 不支援資源重新對應系統。若要根據語言的腳本使用不同的字形,請改用 DynamicFont 後備系統,它允許您定義任意數量的後備字形。
DynamicFont 後備系統的優點是,無論目前語言如何,它都可以工作,這使其非常適合文字語言可能與客戶端語言不配對的多人聊天等情況。
自動設定語言
It is recommended to default to the user's preferred language which can be
obtained via OS.get_locale_language().
If your game is not available in that language, it will fall back to the
Fallback
in , or to en if empty.
Nevertheless, letting players change the language in game is recommended for
various reasons (e.g. translation quality or player preference).
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: 英文(德國)
獨立遊戲一般只需要關心語言,但請繼續閱讀以獲得更多資訊。
Why locales exist can be illustrated through the USA and Great Britain. Both speak the same language (English), yet differ in many aspects:
Spelling: e.g. gray (USA), grey (GB)
Use of words: e.g. eggplant (USA), aubergine (GB)
Units or currencies: e.g. feet/inches (USA), metres/cm (GB)
然而,這可能會變得更複雜。假設您在歐洲和中國提供不同的內容 (例如在大型多人線上遊戲中)。您需要將各種不同的內容翻譯為多種語言,並據此進行儲存和載入。
將鍵轉換為文字
Some controls, such as Button and Label,
will automatically fetch a translation if their text matches a translation key.
For example, if a label's text is MAIN_SCREEN_GREETING1 and that key exists
in the current translation, then the text will automatically be translated.
This automatic translation behavior may be undesirable in certain cases. For
instance, when using a Label to display a player's name, you most likely don't
want the player's name to be translated if it matches a translation key. To
disable automatic translation on a specific node, set the Auto Translate > Mode
to Disabled in the inspector.
在程式碼中, 可以使用 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 <https://www.google.com/get/noto/>」。如果您使用的是不太常見的語言,請確保下載正確的變體。
下載字形後,將 TTF 檔案載入到 DynamicFont 資源中,並將其用作控制節點的自訂字形。為了獲得更好的可重複使用性,請將新的主題資源關聯到根控制節點,並將 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);
如有需要,也可以與語境(context)結合使用:
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);
讓控制項可調整大小
不同語言的相同文字的長度差異很大。為此,請務必閱讀教學 尺寸與錨點,因為動態調整控制項大小可能有所説明。Container 可能很有用,Label 的文字換行選項應該也能幫上忙。
要檢查你的 UI 是否能容納比原文更長的譯文,可以在進階專案設定中啟用 pseudolocalization。這會將所有可在地化的字串替換為更長的版本,同時把原字串中的部分字元換成帶重音(仍可辨識)的版本。佔位符會保持不變,以確保在啟用偽本地化時仍可正常運作。
例如,當啟用偽本地化時,字串「Hello world, this is %s!」將變為「[Ĥéłłô ŵôŕłd́, ŧh̀íš íš %s!]」。
雖然第一眼看上去很奇怪,但是偽當地語系化的好處有很多:
它可以讓您快速發現不可本地化的字串,這樣您就可以檢查它們並使它們可本地化(如果這樣做有意義的話)。
它可以讓您檢查無法容納長字串的 UI 元素。許多語言的翻譯都會比原始文字長得多,因此確保您的 UI 能夠容納比平常更長的字串非常重要。
它讓您檢查您的字型是否包含支援各種語言所需的所有字元。然而,由於偽本地化的目標是保持原始字串可讀,因此它不是一個有效的測試,無法檢查字型是否能支援 CJK 或由右至左書寫的語言。
專案設定可讓您調整偽本地化行為,以便您可以根據需要停用其部分內容。
TranslationServer(翻譯伺服器)
Godot 具有一個處理底層翻譯管理的伺服器,稱為 翻譯伺服器。可以在執行期間新增或移除翻譯;目前的語言也可以在執行期間變更。
Bidirectional text and UI mirroring
阿拉伯語和希伯來語是從右到左書寫的(除了混合的數字和拉丁單字),這些語言的使用者介面也應該是鏡像的。在某些語言中,字形的形狀會根據周圍的字元而變化。
對雙向書寫系統和 UI 鏡像的支援是透明的,您通常不需要更改任何內容或了解特定書寫系統。
對於 RTL(從右至左)語言,Godot 會自動對 UI 進行以下調整:
鏡像左右錨點和邊距。
交換文字的左對齊和右對齊。
鏡像容器中子控制項的水平順序以及 Tree/ItemList 控制項中專案的水平順序。
Uses mirrored order of the internal control elements (e.g., OptionButton dropdown button, CheckBox/CheckButton alignment, List column order, TreeItem icons and connecting line alignment). In some cases, mirrored controls use separate theme styles.
Coordinate system is not mirrored.
Non-UI nodes (sprites, etc.) are not affected.
可以使用下列控制項屬性來覆寫文字和控制項佈局方向:
text_direction, sets the base text direction. When set to "auto", the direction depends on the first strong directional character in the text according to the Unicode Bidirectional Algorithm.language, overrides the current project locale.The
structured_text_bidi_overrideproperty and_structured_text_parsercallback, enable special handling for structured text.“layout_direction”,覆蓋控制鏡像。
也參考
您可以使用 BiDI 與字型功能示範專案 來實際查看由右至左排版是如何運作的。
將斷詞資料新增到匯出專案
有些語言書寫時不使用空格。對於這些語言,斷詞與換行需要不僅僅是字元序列規則。Godot 包含基於 ICU 規則與字典的斷詞迭代器資料,但在匯出的專案中預設不會包含這些資料。
To include it, go to and enable Include Text Server Data, then export the project. Break iterator data is about 4 MB in size.
結構化文字 BiDi 覆寫
Unicode BiDi 演算法設計用於處理自然文字,它無法處理具有更高層級順序的文字,例如檔案名稱、URI、電子郵件地址、正規表示式或原始程式碼。
例如,所顯示的目錄結構的路徑將顯示不正確(頂部「LineEdit」控制項)。 「檔案」型別結構化文字會覆寫將文字分割成段,然後將 BiDi 演算法單獨套用到每個段,以正確顯示任何語言的目錄名稱並保留資料夾的正確順序(底部「LineEdit」控制項)。
自訂回調提供了一種覆蓋其他型別結構化文字的 BiDi 的方法。
數字本地化
專門設計用於數值輸入或輸出的 Control (例如 ProgressBar、SpinBox) 將會自動使用本地化數字系統,對於其他 Control,TextServer.format_number(string, language) 可用於將西方阿拉伯數字 (0..9) 轉換到本地化數字系統,以及 TextServer.parse_number(string, language) 將其轉換回來。
圖示與圖片本地化
帶有左右指向箭頭的圖示可能需要在阿拉伯語和希伯來語語言環境中顛倒過來,以防它們指示移動或方向(例如後退/前進按鈕)。否則,它們可以保持不變。
翻譯測試
在發佈前你可能會想測試專案的翻譯。Godot 為此提供三種方法。
Under (with advanced settings enabled) 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).
請記住,因為這是一個專案設定,設為非空時會在版本控制中顯示。因此,將修改提交到版本控制之前,應該將其設回空值。
其次,在編輯器中前往上方選單點選 ,接著前往 Preview Translation 並選擇你想預覽的語言。
此時編輯器中場景的所有文字應會以所選語言顯示。
翻譯也可以在 從命令列執行 Godot 時 測試。例如,若要測試法文的遊戲,可以提供以下引數:
godot --language fr
專案名稱翻譯
The project name becomes the app name when exporting to different operating systems and platforms. To specify the project name in more than one language go to . From here click on the button, then the button. It will take you to a page where you can choose the language (and country if needed) for your project name translation. After doing that you can now type in the localized name.
如果您不確定要使用的語言代碼,請參閱 語言環境代碼列表。