Translating a Unity game
There is multiple ways how you can translate your game. For our purpose where we need to translate mostly the UI elements. The solution is not complete or future proof. For example the code can not be used for translating plurals or anything more fancy than just simple text.
Dictionary
Each library doing translations of text work pretty much on the same technique. You have a dictionary where you find a phrase based on the key.
We use a JSON file for each language that we do support. Let's take a look into our dictionary file (JSON #1).
We have a list of objects that contain the key
and value
. The key
is used by us in the code and the Unity inspector. The value
is shown to the user/player.
Because sometimes a word can have multiple meanings in another language. e.g. Die (to cease living / a cube marked with numbers one through six) we use more verbose key naming strategy. Otherwise, it might be impossible to translate a UI. Although this might be a very stupid example (image #1), I think you are getting the point and why you should name the key
by its true meaning. Otherwise, you could end up with a result that is not far away from Google translate.
Therefore we are using a unique key
that is bound by the dot notation to the scene and it's meaning instead of the word itself.
Using JSON #1 and key MENU.SETTINGS.MAIN.FX.LABEL_TEXT
will get translated into FX
in the game itself.
We will explain the way how it is done in the following sections. We take a look at how we use our custom component to get the translation from the dictionary. And then we take a look at how is the JSON parsed into some structure that is fast for searching and easy to maintain. But first, let's show how we get the user selected locale.
Getting the locale of a player
You can have a value of the selected language stored somewhere in the player prefs and language switch component that changes the desired language.
Since we are building a mobile game, we determine the user language from the language of his OS.
GetSupportedLanguageCode
method helps us to map a user system language to a language that we do support. For now, we have only Czech and English version of the localization files. We also introduce a fallback in GetDefaultSupportedLanguageCode
which returns an English. So every other language than Czech will get the English version. This is easily extendable and we can add more languages in the future.
The value provided by the GetSupportedLanguageCode
will be used later on while we will parse the JSON.
LocalizedText Unity component
The component is simple. It requires to be attached to a game object that has Text
component. LocalizedText component will replace the current value of the Text
component using a localizationKey
field value from the Unity
inspector.
It communicates with the JSON through a LocalizationManager
which we will cover in the next section. For now, you just need to know that it will search the JSON for a key
field and use its value
to replace the text in the Text
component.
LocalizationManager — JSON Parsing
The only thing that we need is to parse the correct file. To have all the files available during runtime you need to place them into the StreamingAssets
folder. So our directory structure for localization files is Assets > StreamingAssets > Locale. The files are named by the supported locale from the LocaleHelper
(see the code above). So English version of the JSON dictionary file is located at Assets > StreamingAssets > Locale > locale_en.json.
The LocalizationManager is present on the loading scene. Loading scene has a script that blocks another scene (menu) to load until the pre-conditions are met. It can be various things and one of them is our LocalizationManager. I have attached an example code of the loading scene at the bottom of this article.
Let's take a look into the methods defined in the LocalizationManager.
During the Start
lifecycle method we keep yielding until the file is loaded and parsed.
LoadJsonLanguageData
will try to load the file contents for the user OS locale. If it fails it will try to load the default locale which is English. Parse the file and create a Dictionary<string, string>
that is used to retrieve the value of translation for the specified key in the GetTextForKey
method.
Loading Scene
If you are interested in how we implemented our Loading scene. Here is an example. How you will show your loading scene is totally up to you. We are having a logo of the game attached to it. Besides the visual parts, there is a Game Object containing one script LoadingSceneManager
that checks if the LoadingSceneManager
is ready. This way the first scene loads only when the JSON has been parsed and the Dictionary
is available.
Please feel free to leave a comment in case I missed something and you do not understand a part. As I mentioned this is far away from any superior solution, but it can be extended to support anything you need.
Also, I would like to mention articles from my colleagues. Awesome article about automated testing in Unity by Jan Slifka and more at our Medium profile.
These were some examples and tips that we found out during the development of our game Sine.
We are Lonely Vertex, a small indie game studio located in Prague, Czech Republic. Currently getting ready to release our first game, Sine. You can subscribe for newsletter, read our development blog posts or follow our progress on Twitter, Instagram or Facebook.