In Unreal Engine 4, we have a method for collecting all the localizable text in source code and content browser assets and saving it into files for translation.
An overview of our Localization system is here:
Localization > Localizing Text > Overview
Previously, in order to get your project ready for the gathering of localizable text there was a good amount of setup you needed to do, then the actual collection was done with commandlets (small applications run on the command line) that would do the gathering for you.
Enabling the Localization Dashboard
In a future version of UE4, we want to make this process a lot friendlier, so we are currently developing a UI frontend for the localization system that we are calling the âLocalization Dashboardâ.
This feature is currently in development, but in the main branch (and probably 4.8) itâs available in an âexperimentalâ state for adventurous users to try and provide feedback (in other words, itâs by no means production ready). To access it, first you must enable the feature in the Editor Preferences: Experimental section:
When you do this, it makes the âLocalization Dashboardâ menu item available via the Window menu (this may not be the permanent location for accessing the Localization Dashboard, but it is currently accessible from here):
Adding a target for localization
From here, you can add a new Target for localization:
These targets become separate files on disk and you can choose which ones to load or not load. You can also add additional ones later for downloadable content, etc.
Currently, when adding a new target, the target is added to the Content/Localization/TargetName folder. This folder is not included automatically in the list of localization directories that are loaded when your game starts, but for now we can add it manually in a config file (in the future this should be made more automatic). In the DefaultEngine.ini file in your projectâs Config directory, add a line like the following:
[Internationalization]
+LocalizationPaths=%GAMEDIR%Content/Localization/NewTarget
Where âNewTargetâ is the name of the localization target you just added.
Back in the Localization Dashboard, the settings of the new localization target that was added can be modified by clicking on the name of the target:
In the new targetâs properties, you can define which text files (source code files), packages (content browser asset packages), and metadata (comments in the code used to create tooltips in the editor), that the target should gather (you can also define which other targets this target is dependent on, but we wonât get into that right now):
The directories Iâm specifying here are relative to the project directory, and here Iâm specifying the ./Source directory for text files, since this is where all the source code text files exist, and ./Content for the Packages search directories, since all content browser content lives here. Right now these include paths are text fields that you have to type paths into in a specific way, but eventually there will be a button to pop up an operating system folder picker dialog, which will then be converted into a path relative the correct directory automatically. Also, for file extensions, Iâm specifying â.uassetâ for Content Browser assets, and â.cppâ â*.hâ for text files. Weâll probably make something like this the default for most projects but for now itâs a little manual.
Adding a new culture
Below this, in the âCulturesâ section you can choose the Native culture. For our projects the native culture is English because we are an English-speaking company so all the source text is written in English, but it is possible to define the source language as a different language. You can also add new cultures for localization here as well with the Add New Culture button:
Here I will choose Japanese (Japan) (ja_JP) from the list of cultures:
Adding text to localize
From here, we need to add some text to our project to gather.
In a previous blog post Justin Sargent described how to add localization ready text to your project:
Creating a localization ready game in Unreal Engine 4: Part 1-Text
First I will add a Blueprint class with some text to translate. You can create a new Blueprint class by opening the Add New menu in the Content Browser, and selecting âBlueprint Classâ
In the Blueprint Class Editor, click the new variable button, and give your variable a name:
Then once you compile your Blueprint class, you can enter the actual text to translate in the default value of the variable:
Next, I will add a C++ with some localizable text.
Iâll select âNew C++ Classâ from the file menu, and create a new C++ class with no parent:
Iâll call the new class MyClass:
In the resultant MyClass.cpp in your projectâs Source directory, Iâll add the following Localizable text macro:
MyClass::MyClass()
{
FText TestHUDText = NSLOCTEXT("Your Namespace", "Your Key", "Your Text");
}
Gathering the text
Now that there is some text in this project, it can be gathered into text files for the localization process⊠Back in the localization dashboard, by pushing the âGatherâ button in the target created earlier, the gather process can be started:
There will be a progress bar showing the status of the gather:
Now if you look in your projectâs Content > Localization folder, youâll see a folder for your new target, and inside that folder will be various files including the .manifest that contains all the source text information:
After gathering, the manifest file now contains information about the two pieces of source text added:
{
"FormatVersion": 1,
"Namespace": "",
"Children":
{
"Source":
{
"Text": "Text to translate "
},
"Keys":
{
"Key": "E0A3DC654F9EAE9C6E41D4BD38FEC632",
"Path": "/Game/TestLoc.Default__TestLoc_C.SomeText"
}
]
}
],
"Subnamespaces":
{
"Namespace": "Your Namespace",
"Children":
{
"Source":
{
"Text": "Your Text"
},
"Keys":
{
"Key": "Your Key",
"Path": "Source/SampleLoc/MyClass.cpp - line 8"
}
]
}
]
}
]
}
Also there are separate folders for each culture you added to your project, and inside of those files there is an .archive file containing all the translation information:
At this point, the file contains two entries for the two pieces of text added earlier, but no translations have been added:
{
"FormatVersion": 1,
"Namespace": "",
"Children":
{
"Source":
{
"Text": "Text to translate "
},
"Translation":
{
"Text": ""
}
}
],
"Subnamespaces":
{
"Namespace": "Your Namespace",
"Children":
{
"Source":
{
"Text": "Your Text"
},
"Translation":
{
"Text": ""
}
}
]
}
]
}
(There is even an archive for the native culture, the only difference being that this archive has itâs translation field filled automatically for every piece of text with the source text.)
Translating the text
The .manifest and .archive files are not intended to be hand-edited because we believe hand-editing text files makes for an unfriendly and error-prone workflow. Back in the Localization Dashboard you can click on the âEdit Translationsâ button to open the translations for each language and modify them (there are also buttons for exporting and importing from .po files if you want to want to use a different software for localizing these texts):
This opens the Translation Editor, which itself is still a work in progress but can be used to translate text into other languages and save the changes back to the .archive file for that language.
You can edit translations here or export them to .po (portable object) format for import and editing in your translation tool of choice, and then import them back into the .archive in UE4 later.
The Translation Editor splits your localizable text into 3 tabs, âUntranslatedâ and âCompletedâ are self-explanatory, but if you have source control enabled and you retrieve the history of your translations via the âGet HistoryâŠâ button, the âNeeds Reviewâ tab will show any text that was translated but for which the source text later changed, providing an easy mechanism to make small tweaks to reflect the changes to the source text in your translated text. The âContextâ tab will show the Namespace and Key that uniquely identify a piece of localizable text, and any additional context such as the name of the source file or asset this text came from.
Saving the changes made in the Translation Editor and looking at the .archive file again shows the results have been reflected here:
{
"FormatVersion": 1,
"Namespace": "",
"Children":
{
"Source":
{
"Text": "Text to translate "
},
"Translation":
{
"Text": "çż»èšłăăăăăăčă"
}
}
],
"Subnamespaces":
{
"Namespace": "Your Namespace",
"Children":
{
"Source":
{
"Text": "Your Text"
},
"Translation":
{
"Text": "ăăȘăăźăăăčă"
}
}
]
}
]
}
Back in the Localization Dashboard, there is a display to show you what percentage of your target has been translated into the various cultures you added. If you now hit the âCount Wordsâ button, it will update this display to show that everything has been translated:
Compiling to binary format
So far we have created FText source texts, gathered these into .manifests and .archives, and added translations for additional cultures. But UE4 does not use the contents of.archive files directly when launching your game. It instead uses a binary .locres (Localization Resource) file. So lastly, in order to generate this file, we can use the âCompileâ button:
Launching the game in different cultures
Finally, letâs look at how to choose which culture the game will use when you launch it. To see which region is being chosen, Iâll print the localized text we added to a blueprint earlier. Iâll open up TestLoc and add a quick print text:
Now Iâll save that Blueprint and place an instance of it in the level.
For various reasons, itâs not possible to load anything but the source text when doing Play-in-Editor (currently it would overwrite the source text with localized text if you made any changes), so we have to launch the game as a separate process to verify. The quickest way to verify is by launching a Standalone game from the Editor.
From the play menu drop down, choose Advanced Settings:
In the Play in Standalone Game section, click the drop-down arrow to expose more settings:
In âAdditional Launch Parametersâ add -culture=CultureName where CultureName is the 2 or 4 letter code that identifies a culture by language or language and region combo, such as âenâ for English, âen_USâ for English (United States), or âja_JPâ for Japanese (Japan), etc. (this will match the culture folder names inside of your Content/Localization folder):
From there, select âStandalone Gameâ from the âPlayâ menu drop down to launch a new Standalone game:
The text I translated earlier for the ja_JP culture now displays:
This debug text soon disappears, so you can open the console by pressing the console key twice to view the console history in the case you miss it:
Now if you go back and change Additional Launch Parameters to read â-culture=enâ, the original source text will be displayed. (This also happens if you donât specify any culture, it will display the default culture):
Cooking and packaging localized games
For cooked games, the culture setting can also be set in your projectâs configuration files, specifically DefaultEngine.ini in the Config folder of your Project, by adding a section like this:
[Internationalization]
Culture=ja_JP
When cooking your project via UnrealFrontend or the new Project Launcher (available from the Window menu), you can select which languages to cook:
Additionally when packaging your project you can select which languages you want to package:
One last thing you need to be careful about when packaging is, with the above packaging settings, you chose which locales you want to package your localization data for, but Unreal Engine also needs ICU to know which locales exist. Because the ICU data itself for each locale is not small, we only include English by default, so you will need to pick a different setting for âInternationalization Supportâ in Packaging settings:
(see this post for screenshot)
Thatâs pretty much all there is to explain currently, but rest assured weâll continue to improve the localization workflow in newer versions of UE4!