Get-text style localization in Unity

In past Unity projects I have used basic string table lookup to localize UI text using carefully named keys. Whilst straightforward in terms of implementation this has a number of downsides such as being unable to properly handle the plural forms of some languages; not to mention the problem of having to come up with meaningful keys and locating strings in source code.

With get-text the default language strings are used as the keys for localized text and there is provision for dealing with multiple plural forms as well as providing extra semantics such as context and proper names.

So why change now? Well, since I am in the process of releasing packages with open source licenses I realize that it will be easier for anyone wanting to use or contribute to maintain the software or create new localizations. The open source gettext tooling and POEdit are fantastic tools to manage localizations.

I’ve created a simple wrapper library around an open source MIT-licensed NGettext implementation for C# (compatible with AOT platforms). It is up to user code as to how language domains are structured and loaded. In my projects the language domains would be initialized at the composition root and then injected into the various UI components.

For example,

labelNameField.text = this.lang.ParticularText("Input", "Name");

Language domains for editor extensions can be defined by creating a new class that extends the PackageLanguage<T> generic class:

public sealed class MyPackageLang : PackageLanguage<MyPackageLang>
    public MyPackageLang()
        : base("@my-vendor-name/my-package", CultureInfo.GetCultureInfo("en-US"))

    // Custom functionality can be implemented here if required...

Editor text can then be localized using the MyPackageLang class:

GUILayout.Label(MyPackageLang.Text("Create new instance using a template:"));
prefab = GUILayout.ObjectField(MyPackageLang.ParticularText("Property", "Prefab"), prefab);

Localizations are provided in the compiled .mo format which can be placed into the package’s “Languages” folder “Plugins/Packages/@my-vendor-name/my-package/Languages” or into the package’s data folder “Plugins/PackageData/@my-vendor-name/my-package/Languages”.