Simple text localization in Unity

8/6/2016 8:07:11 PM

Localization can help your game reach more people and is fairly easy to do. The best way to do that is having a text file for each languages that is easy to read and edit for people who will translate your text and who might not be technical at all. If you translate your game yourself it's still very practical to have language text files that you can edit with a simple text editor.

 

The file can be a simple .ini formated file, json or xml. Each format has its pros and cons. I believe ini files are the easiest for human to parse but lack flexibility. Json is easier to parse by computer but hard to understand when you read it. I personnaly like xml, it's still hard to read sometimes but you can always format it in a way that stay simple enough to edit by hand. Also xml has build in support with c# and it's really easy to parse.

 

For my game In The Shadows I use a simple localization system based on xml files. I am sharing the basics of it here so that you can use it and extend on it if you find it useful. I tried to make the simpliest yet usable localization system I could think of for localizing text in a game here. I guess this tutorial is targeted to people with a moderate level of knowledge of C# and Unity.

 

XML format

Let's start defining the xml file structure. I will keep the example simple so it's easier to explain. This file will be saved somewhere in your project Assets folder. Save this file as ENGLISH.xml

 

<?xml version="1.0" encoding="utf-8"?>
<Language LANG="english" ID="0">
  <!-- Main Menu -->
  <text key="MAIN_TITLE">My Game Title</text>
  <text key="CONTINUE">Continue</text>
  <text key="START_NEW_GAME">Start New Game</text>
  <text key="OPTIONS">Options</text>
  <text key="QUIT">Quit</text>
</Language>

 

The structure here is very simple. Easy to parse and easy to edit manualy. The main root node of the xml file define the language and the ID attribute will be used set the language used ingame. Set a different ID to each language file.

 

Then I use a "text" node with a "key" attribute and the value of the node is the actual text that we will see in-game. With this system each language has it's own file and you just need to edit the "text" node value for each language. The node "key" attribute stay the same for each language. This file is saved in the Asset folder under the filename "ENGLISH.xml". If you have a file for french name it "FRENCH.xml" and so on.

 

Now we need a way to read the language xml file content to use the key value pair in the game.

 

Localization Class

This is a simple class that will read and populate itself with the xml content. You simply need to add this script to an empty GameObject that will stay in all your scenes. Save this file as LocalizationManager.cs

 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;
 
public class LocalizationManager : MonoBehaviour
{
    public static LocalizationManager Instance { get { return instance; } }
    public int currentLanguageID = 0;
    [SerializeField]
    public List<TextAssetlanguageFiles = new List<TextAsset>();
    public List<Languagelanguages = new List<Language>();
 
    private static LocalizationManager instance;   // GameSystem local instance
 
    void Awake()
    {
        instance = this;
        DontDestroyOnLoad(this);
        // This will read  each XML file from the languageFiles list<> and populate the languages list with the data
        foreach (TextAsset languageFile in languageFiles)
        {
            XDocument languageXMLData = XDocument.Parse(languageFile.text);
            Language language = new Language();
            language.languageID = System.Int32.Parse(languageXMLData.Element("Language").Attribute("ID").Value);
            language.languageString = languageXMLData.Element("Language").Attribute("LANG").Value;
            foreach (XElement textx in languageXMLData.Element("Language").Elements())
            {
                TextKeyValue textKeyValue = new TextKeyValue();
                textKeyValue.key = textx.Attribute("key").Value;
                textKeyValue.value = textx.Value;
                language.textKeyValueList.Add(textKeyValue);
            }
            languages.Add(language);
        }
    }
    // GetText will go through each language in the languages list and return a string matching the key provided 
    public string GetText(string key)
    {
        foreach(Language language in languages)
        {
            if (language.languageID == currentLanguageID)
            {
                foreach(TextKeyValue textKeyValue in language.textKeyValueList)
                {
                    if (textKeyValue.key == key)
                    {
                        return textKeyValue.value;
                    }
                }
            }
        }
        return "Undefined";
    }
}
// Simple Class to hold the language metadata
[System.Serializable]
public class Language
{
    public string languageString;
    public int languageID;
    public List<TextKeyValuetextKeyValueList = new List<TextKeyValue>();
}
// Simple class to hold the key/value pair data
[System.Serializable]
public class TextKeyValue
{
    public string key;
    public string value;
}

 

Some details about what is going on in this script : 

 

The class use DontDestroyOnLoad(this);  so the GameObject holding the script will stay in scene even after you load a new scene. You can add your localization gameobject on the first scene you load or use any other mean of scene management that you already have.

 

Using [SerializeField] over the languageFile List<> will embed that list in Unity inspector so you can easily drag and drop your XML file in there inside the editor. The script uses [System.Serializable] to embed the language sub classes in Unity inspector to easily visualise the data and help debuging. 

 

The variable currentLanguageID will define which language file to use. You can set this value any way you want, it has to match the ID value from the XML file you want to use. Here it is set to 0 so it will use the English.xml file since its ID attribute is set to 0. You could detect the system language to set this value to the system current language and use a menu / option that the player can change manually. 

 

The script in the inspector. You can drag and drop your xml file in the Language File List<> 

 

Localized UI Text component

You will also need a second script that you add to your GameObject with a UI Text component. Save this file as LocalizationUIText.cs

 

using UnityEngine;
using UnityEngine.UI;
 
[RequireComponent(typeof (Text))]
public class LocalizationUIText : MonoBehaviour
{
    public string key;

    void Start()
    {
        // Get the string value from localization manager from key & set text component text value to the returned string value
        GetComponent<Text>().text = LocalizationManager.Instance.GetText(key);
    }
}

 

This script can be added to any GameObject with a Text component on it. It can be the Text Component of a button or just a label or whatever. This script simply calls GetText() from the LocalizationManager and populate the Text component text value with the string returned.

 

The [RequireComponent(typeof (Text))] line will add a Text Component to the GameObject to which you added the script, if there is not one already attached to it.

 

Add the script to a GameObject with a UI Text component. Set Key to the value you want to use in the XML file.

 

You can now specify the Key to use for this particular Text component text value. The text value will be automaticly changed by the localization script.

 

You can also use the LocalizationManager in other scripts, if you need to set a string in UI to different value programmaticaly, you can simply call the GetText() method with the Key you want to use.

 

string localizedString = LocalizationManager.Instance.GetText("START_NEW_GAME");

 

This will return the string "Start New Game" in the language specified by currentLanguageID from LocalizationManager.

 

To conclude

Well thats pretty much it. This is a very simple way to handle localization I think, there is ways to make extremely flexible localization system that will also handle images or sound, but I wanted to share a simple way to localize text, while still using an extenal file format that you can easily modify by hand. In The Shadows uses something similar to this altho I do handle image localization as well, but that was out of scope for a simple tutorial. Maybe this example will be useful to you or give you ideas for your own system.

 

 

This is the second part of a series of articles on my thoughts on creative process. This time I’ll be talking about my personal experience learning computer programming and electronics. You can read the first part here.

 

Atari 800XL


In 1983 Atari released the 800XL computer. Some years later, it became the first computer I ever used. Atari BASIC was very simple to learn. It was the best way to tinker with computers as a kid, messing with programs listings and trying to make interesting graphics.

 


My resident Atari kit sitting on my desk in my home workshop

 

 

8 Bit processors are very interesting. They are very simple in design by today’s standards. The limitations at the time made programming a lot easier in some aspect, even though you would program on a much lower level than with programming languages most used today. Peeking and poking memory locations directly. This was my introduction to computers and programming. For me using a computer already meant programming and creating, not using it passively to consume data the way computers are most used for today. 

 

 


Analog Computing. We used to type those program listings by hand.

 

 

Programming, production pipeline and workflow 


I studied programming for about a year, dropped out and went on to study 3D animation, putting code behind me. Funny thing is, while working in 3D animation, I realized how programming, or more precisely scripting could make my life so much easier. There is a lot of repetitive work in production and I would always script something to make my work go faster. I got obsessed with optimizing my work, to the point that years later, making CGI was not even on my mind anymore. The ultimate goal was to make the production of CGI more efficient. 


I ended up working on 3 different assets managers  and tracking softwares in my technical director career since 2006. Assets managers and trackers are interesting pieces of software. They are used to track your assets, schedules, communications, versioning, etc... during production. When you build a software like this, you really need to find the best way to optimize not only your own work, but also the work of anyone else working on a project. It require a lot of design on paper before doing anything at all, which is something I am not used to. One thing I do get obsessed with is finding the best workflow to work; it’s very meta in nature since the tool I’m designing can also help me work on the tool itself better. Eating your own dog food in software development is always interesting. I think for non devs to understand what software development means there is many book that touch the subject, but one that I enjoyed a lot is  “Dreaming in Code”.

 

After working in 3D animation for a decade you realise that some people think they can choose not to be technical for some reasons. I heard so many “artists” say that they “don’t want to be technical”. If you are working on a computer all day long... it’s your tool. You need to know some basic things about the inner working of your tool. Painters know how their brushes work, they know how to clean them and keep them in good working order. Know your tools. My quest for a perfect asset manager and tracker was really to make the perfect tool to work, finding a way to work as fast as possible. 

 

 

Putting it all together, Midi to Atari


I think that sometimes you need to have a clear idea of what you want to build and design. Sometime you might not have the exact skills needed for a particular task, but you can learn those skills. In 2013 I build a Midi to Atari Controller. I wanted to make music with the real, pure sound of an atari computer and I came up with a solution that was pretty neat using and Arduino controller. Arduinos are easy to learn, and you can do pretty much anything you want with it. 

 

 


Totally staged picture of electronic stuff in my home workshop

 

 

Here is how I came up with the idea and my thought process. I wanted to make chiptunes for a game project on my Atari 800XL. When you have a goal with a lot of unanswered questions it’s good to look at it from afar and break it down to solve all the possible problems one by one. A midi controller for the Atari 800XL means the following:

 

  • A way to send Midi signal to an Arduino board (electronics)
  • Process that signal on the Arduino (software)
  • Send that signal to the Atari somehow (electronics)
  • Process that signal on the Atari (software)

 

Programming with the 1980s Atari Basic was just not practical, so I started working with OSS “Action!”. It’s a programming language that looks and work a lot like C. It’s much easier to work with.


The way the whole thing work is simple. The Midi controller send a Midi signal that the Arduino read in serial. It’s a command, a note and a velocity. The Arduino then send a signal to the Atari using the two controller port. Using 8 inputs at the same time I could send 8 bit simultaneously. First the command byte, wait, then the note byte. Probably not the best way to do this but it worked! The Atari would then use the command and note to play back a tone. I wanted the synthesizer to be polyphonic and used all four channel of the Atari to play the same tone but with different pitch. This made for some interesting interference noise.

 

 

Midi to Atari in action, and the badly writen sofware I made in Action! being compiled and run.

 

 

When I learned electronics by myself I didn't know what to do with that knowledge, but I was so glad that I knew some basic stuff when I started working on the Midi to Arduino board. Also I can fix a bunch of electronic stuff at home now, turns out soldering skills is actually pretty useful.

 

Game development


I apply the same process when working on my game. The same kind of situation happened when I was trying to figure out how to make the game work with shadows and real-time lighting in 3D. If I have a problem, what can I use in my current skills set to solve it? It might not be the best solution, but if it works, it works. I can always go back to it and fix it later, but at least I got things done and had a result really fast. You should just do something, get something done, it doesn’t have to be perfect, but by working on it you might get new ideas and make it better later. Find the best way to do something really fast, because the faster you can make it, the faster you get a result, even if it's not perfect, at least you made something. It’s always better than doing nothing.

 

Working in 3D animation for such a long time then working on ways to optimize my work made me realise how much I loved programming, but I also missed making visual. I worked on a short film for a while, but ultimatly making a video game was always on the back of my mind. Making games seamed a lot harder back then, at least it was not as easily accessible as it is today. Now most people who play games know about engines and Unity or Unreal, the fact that there is tons of indie devs is common knowledge now. So I just took a chance, working on my small project, but did I? I knew how to make it before I started working on it really, I tried to figure out the best way to build my game, the fastest way. It still took 2 years at this point, and it's not done yet! 

 

 

In the next article I will talk about my creative process more in detail, how to be a one man team, being multidisciplinary and what I think it mean to be creative in my opinion.

 

 

 

I wanted to write about my creative process, but soon realised that there was a lot of background information needed to understand my point of view. I was asked before about my work in 3D animation before starting to do game development and I thought it could be interesting to share my experience. I will make a multi part post that will talk about my personal filmmaking experience, programming experience and what brought me to game development. My creative process is based on working alone, optimising my work and being independent, and this is the first part. I hope you find it interesting! Knowing about filmmaking helped me in my game development in many ways, if you are just starting like me it might help you as well!

 

 

How it started

 

When I was 16 we got our first modern computer in the house. My older brother would show me things made in 3D like demos and short animations. It was fascinating. He really pushed me to go study in that field, and ultimately that’s what I ended up doing after a failed year studying programming. 


I fell in love with 3D animation.

 

 

CGI 


3D animation back then felt “raw”. At the time, Softimage|3D was very rudimentary. Soon after,  Softimage|XSI  came out and things started to change. I already knew the potential of CGI, but learning it in school made me realise that it was possible to make an entire movie and telling a story by myself.


If you want to be serious about filmmaking, you need to learn the basics. Screenwriting, screenplay and storyboarding are the same for a film or a 3D animated movie. There is a lot of “old school” timeless books with tonnes of information on the subject that I recommend to read to anyone interested in filmmaking. You can tell a story only with moving pictures, you don't even need words.

 

Film directing shot by shot | Film directing cinematic motion | The filmmaker’s handbook

 

I worked in the industry for over a decade. CGI was fun for a while, but if you are a creative person and love your creative freedom, you realise quickly that working in a company doesn't allow you to be very independent, if at all. They call it creative work because you are supposedly an artist, but I never felt that way. You do whatever someone else tells you to do. I did learn a lot while working with others and that was the most important thing really. I worked as a 3D polygonal modeler for a couple of years, specializing in character modeling, then with time I started working more on facial rigging and expressions. As an “all-rounder”, I worked doing lighting, texturing, rendering, rigging, animation, compositing and applied as much as I could in my own work . Being multidisciplinary in any field is always an advantage and CGI is one of those fields where there is  so much to learn, so much to do and it's in constant evolution. Still, I wanted to make a movie all by myself. The fact is that CGI was not even important. CGI was just a tool. I didn’t want people to look at my movies and think of it as a CGI movie, I wanted them to look at it because it’s a movie.

 

Softimage|3D & Softimage|XSI , the first 3D software I learned. Those were the days

 


My Short film : Waste of Space


In 2011 I started working on a personal project, a short film about space exploration, combining two things I am deeply passionate about: space and filmmaking.


Waste of Space: My short film from 2012


Everything was done in CGI. I wanted to make everything myself and I was finally able to do it. This is the culmination of years of self teaching, exploration and curiosity, then applying all this knowledge in different fields to achieve one goal; making a movie. 

 

A shot from Waste of Space

 


Getting work done by your lonesome


When you make a movie by yourself, or any kind of project as a matter of fact, you need to have a vast array of different skills. You have to be independent at least to some extent.  Sometimes you don’t have time to ask for help, you want to work fast, cut corners. Things might not be the best they could, but they are good enough. There is no time to be obsessive about details, there is no time to stop to ask for advices. Once you master a set of skills, you will know where to cut things that will have the least impact on the final result. You are the only one who have the big picture in your head. You know where to put priorities.


Movies are the easiest of art form to consume while being one of the most time consuming to create. CGI movies have an advantage though; you don’t need actors, you don’t need lights, camera, sets, you don’t need to go to a location or rent anything, you can do anything you want on your own computer at home. It just takes time, and that’s why optimising your time become the most important thing you need to do. I might not be the best in any areas, but being proficient in all those different skills help me attains goals by myself. Those same goals that over specialised people, nitpicking over every little details, could never do without a team. Sure, someone who does only texture could say my texture need work, but I don’t have time for that because I was busy lighting, rendering and animating. 

 

Some storyboard panels for Waste of Space

 

I optimize my work as much as I can by storyboarding shots and trying to figure out the fastest way to make them. I will cut corners, I will throw away a shot because it’s too long to make and I will make the shots that get the more bangs for the bucks. I apply this in everything in my life. How can I get 90% of the results with 10% of the effort? Production value.

 

A shot from Waste of Space

 

Production value is crucial when you are independent. When you do everything by yourself, you need to find shortcuts like figuring out the best way to do something that look like months of work even though you crushed it in a week. After all this time learning about CGI, I applied all of my knowledge on my short movie. At the time I could not have known that I would use all of this for one specific goal, but you never know when you learn something today how you're going to use it tomorrow. 

 

 

To conclude


I think it’s important to learn a lot about unrelated things, then combine them to make something new with a fresh perspective that someone specialized in any of those field would not have. By doing so, you have the big picture. I believe it’s important to learn how to do things by yourself, to be independent, to have fast turn arounds. I believe everyone can be passionate about something, in fact many things. All those things might combine one day and you will find a path you did not expect. 


In my next article I will talk about programming and creativity and the path that brought me to game development.

 

New trailer for In The Shadows!

This was made also for the Greenlight campaign which is now over, the game as been greenlit in a week! 

 

 

I might post about the Greenlight process at some point, but I'm not sure. I read so many of those posts and they don't give any meaningful information. Greenlight is a magic box, the only thing I think is important to remember is: if your game looks fun, people vote a lot on it, it not a scam, it will get greenlit. I do want to say thank to everyone who voted, I got around 2900 yes vote on it, with a ratio of more than 70% yes. It feels like people want this game : )

 

The link for the Greenlight page : http://steamcommunity.com/sharedfiles/filedetails/?id=387042861

 

PAXEast

 

In other news I will be at PAXEast 2016 April 22-25 to show the game at the PAX Rising booth section. You can't miss the booth! If you come over on that weekend, come say hi! 

 

 

I thought I could make an article about free software I use a lot. I often need a tool that does one thing in particular and I spend a lot of time finding the right tools that work well, so I compiled this list of lesser known software that anyone can use for free. Also this way when I forgot the names I'll have this list to remember them.

 

First part is about workflow visual / imaging related tools, the second part is more about development tools. Some tools might be well known, other aren’t. If you have suggestions about really nice free tools you use, leave it in the comments sections!

 

Workflow / Image related software:

 

Gifcam - Gif capture software

http://blog.bahraniapps.com/gifcam/

 

 

Gifcam is an easy to use super lightweight gif capture software. You just make a selection of what you want to capture using the software window, you then select what frame rate and the way the color is preserved and press Rec. You can edit the gif with rudimentary options but you can always open the gif in another software if further edit is required.  Windows only.

 

Lightshot – Screenshot capture software

http://app.prntscr.com/en/index.html

 

 

I use this software all the time to take screenshots. You can capture a selected region of your screen, save it, send it, really fast. With a bunch of option and a nice looking interface, Lightshot is really easy to use. Windows and Mac.

 

TurboTop – Always on top any window.

https://www.savardsoftware.com/turbotop/

 

 

This tool is really handy when you want to have a software with no “Always on top” function on top of other windows, like when you work with references while using a painting software, for example. Even when the software you use has a “always on top” function, using TurboTop is easier. You just select the window you want on top from the window system tray and that’s it. Really simple. Windows only.

 

Color Selector 3.0 – Color picker

http://colorselector.sourceforge.net/

 

 

This one still looks like its straight from the 90s but it works perfectly. To quickly pick a color and use the RGB or Hex value in any software this one does the job very well. Windows only.

 

DJV_view – Images/frames sequence viewer

http://djv.sourceforge.net/

 

 

This is a viewer for images/frames sequence. Its super powerful and fast with a tone of options. I used this for many years when I was working in 3D animation and still use it to playback frame by frame animations sometimes. There is just nothing better than this that you can pick up for free, and even paid software sometime don’t even match it. Windows, Mac, Linux.

 

Development related software:

 

DB Browser for SQLite

http://sqlitebrowser.org/

 

Pretty self-explanatory, it a very simple software to browse your SQL Database. I guess this one is known but for those who don’t know it, or are just starting using SQLite in their project, DB Browser is a life saver. Windows, Mac, Linux.

 

Meld – Visual Diff/Merge tool

http://meldmerge.org/

 

Again, self-explanatory, Meld is just the best diff/merge tool I ever used. It looks nice, it works well, you can even compare folders with it or three-way comparison. Can’t ask for more. Windows, Mac, Linux.

 

InnoSetup – Installer script compiler

http://www.jrsoftware.org/isinfo.php

 

My software of choice to make installers before was Nullsoft NSIS, but once I started using InnoSetup I never looked back. It’s easy to use and there is a big community online to help you with specific things you might want to do with your installer. If you want a nice professional looking installer for your game, use this.