[DIY] Need some help supporting localization on a game and updating UI when a language is selected

Hi there,

This is sort of the continuation of a question I posted yesterday. I am aware that many assets exist in the Unity Assets Store, but I would like to do it myself for knowledge sake and “just do it, don’t let your dreams be dreams”.

I would like to support localization in my game, and I was mainly inspired by the Android localization format, meaning storing my strings into .xml files and getting them using a Language Loader :

using CustomDictionary = System.Collections.Generic.Dictionary<string, string>;
using System;
using System.Collections;
using System.IO;
using System.Xml;

public class                    LanguageLoader {

    private CustomDictionary    Strings;
    private string              DefaultString;

    public                      LanguageLoader() {
        this.Strings = new CustomDictionary();
        this.DefaultString = null;
    }

    public void                 Clear() {
        this.Strings.Clear();
    }

    public void                 Load(string path, string countryCode) {
        XmlDocument             xmlDocument;
        XmlElement              rootElement, element;
        IEnumerator             elementEnumerator;

        xmlDocument = new XmlDocument();
        try {
            xmlDocument.Load(Path.Combine(path, this.GetXmlLanguageFile(countryCode)));
            rootElement = xmlDocument.DocumentElement;
            if (rootElement == null || !("language".Equals(rootElement.Name)))
                throw (new XmlException("Invalid root element !"));
            if (!rootElement.GetAttribute("code").Equals(countryCode))
                throw (new XmlException("Country codes are different !"));
            elementEnumerator = rootElement.GetEnumerator();
            while (elementEnumerator.MoveNext()) {
                element = (XmlElement) elementEnumerator.Current;
                if (element.GetAttribute("name") == null || element.InnerText == null)
                    throw (new XmlException("Invalid string !"));
                this.Strings.Add(element.GetAttribute("name"), element.InnerText);
            }
        } catch (XmlException exc) {
            UnityEngine.Debug.LogException(exc);
        }

    }

    public void                 SetDefaultString(string defaultString) {
        this.DefaultString = defaultString;
    }

    public string               GetXmlLanguageFile(string countryCode) {
        return (String.Concat(countryCode.Trim(), ".xml"));
    }

    public string               GetString(string key) {
        string                  returnedString = this.DefaultString;

        if (this.Strings.ContainsKey(key))
            returnedString = this.Strings[key];
        return (returnedString);
    }
}

The .xml language file is well stored and I am able to get a string without any problem. My problem is that I don’t know how to update my UI correctly when a language is selected by the user. For example, I have a main menu which contains four buttons (see the link above for a visual approach) and these four buttons have to be translated using localization. For this, I made a Menu Manager which contains a function that translates the buttons at start, but I find it really gross :

    public void             InitializeMainMenu() {
        this.MainMenu.transform.Find("Character Demo Button").GetChild(0).gameObject.GetComponent<Text>().text = this.Localization.GetString("text_playy_character_demo");
        this.MainMenu.transform.Find("Turn-based Demo Button").GetChild(0).gameObject.GetComponent<Text>().text = this.Localization.GetString("text_play_turnbased_demo");
        this.MainMenu.transform.Find("Languages Button").GetChild(0).gameObject.GetComponent<Text>().text = this.Localization.GetString("text_languages_menu");
        this.MainMenu.transform.Find("Quit Button").GetChild(0).gameObject.GetComponent<Text>().text = this.Localization.GetString("text_quit_game");
        this.MainMenu.SetActive(true);
    }

The further problem is when the user will select a language : is there any Unity function that updates the GUI once ? I heard about OnGUI() but I feel like this is useless to repeat this code every frame.

I apologize if I can’t be more explicit and I’ll try to give you more details as the discussion goes.

Coming back with some good news !

It might help someone in the future so I’ll post my way of doing it. I think I’ll go for custom events : when a language will be selected by the user, an event will be triggered and each gameobject listening to this event will update their text UI. :slight_smile:

The tutorial I linked above is made for Unity 4.x, apparently there is a fresh custom event system (here and there) but I prefer the old one.

Hope it’ll help someone. C: