Translating a Unity game

Jakub Kopriva
Lonely Vertex Development
5 min readSep 3, 2019

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).

JSON #1 — JSON is not valid, the ... represents more items in the list.

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.

image #1

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.

Constants that will be used further down in the code

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.

--

--

Jakub Kopriva
Lonely Vertex Development

Member of indie game studio Lonely Vertex, software engineer since 2015. Responsible for most of the paperwork in company and of course the programming.