Skip to content

Instantly share code, notes, and snippets.

@ditzel
Last active June 30, 2023 21:05
Show Gist options
  • Star 30 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save ditzel/2546768f28df7ca664de4a8dfbbfc778 to your computer and use it in GitHub Desktop.
Save ditzel/2546768f28df7ca664de4a8dfbbfc778 to your computer and use it in GitHub Desktop.
Internationalization - See code comments for usage
/*
* Internationalization
*
* Author: Daniel Erdmann
*
* 1. Add this File to you Project
*
* 2. Add the language files to the folder Assets/Resources/I18n. (Filesnames: en.txt, es.txt, pt.txt, de.txt, and so on)
* Format: en.txt: es.txt:
* =============== =================
* |hello=Hello | |hello=Hola |
* |world=World | |world=Mundo |
* |... | |... |
* =============== =================
*
* 3. Use it!
* Debug.Log(I18n.Fields["hello"] + " " + I18n.Fields["world"]); //"Hello World" or "Hola Mundo"
*
* Use \n for new lines. Fallback language is "en"
*/
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
class I18n
{
/// <summary>
/// Text Fields
/// Useage: Fields[key]
/// Example: I18n.Fields["world"]
/// </summary>
public static Dictionary<String, String> Fields { get; private set; }
/// <summary>
/// Init on first use
/// </summary>
static I18n()
{
LoadLanguage();
}
/// <summary>
/// Load language files from ressources
/// </summary>
private static void LoadLanguage()
{
if (Fields == null)
Fields = new Dictionary<string, string>();
Fields.Clear();
string lang = Get2LetterISOCodeFromSystemLanguage().ToLower();
//lang = "de";
var textAsset = Resources.Load(@"I18n/" + lang); //no .txt needed
string allTexts = "";
if (textAsset == null)
textAsset = Resources.Load(@"I18n/en") as TextAsset; //no .txt needed
if (textAsset == null)
Debug.LogError("File not found for I18n: Assets/Resources/I18n/" + lang + ".txt");
allTexts = (textAsset as TextAsset).text;
string[] lines = allTexts.Split(new string[] { "\r\n", "\n" },
StringSplitOptions.None);
string key, value;
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].IndexOf("=") >= 0 && !lines[i].StartsWith("#"))
{
key = lines[i].Substring(0, lines[i].IndexOf("="));
value = lines[i].Substring(lines[i].IndexOf("=") + 1,
lines[i].Length - lines[i].IndexOf("=") - 1).Replace("\\n", Environment.NewLine);
Fields.Add(key, value);
}
}
}
/// <summary>
/// get the current language
/// </summary>
/// <returns></returns>
public static string GetLanguage()
{
return Get2LetterISOCodeFromSystemLanguage().ToLower();
}
/// <summary>
/// Helps to convert Unity's Application.systemLanguage to a
/// 2 letter ISO country code. There is unfortunately not more
/// countries available as Unity's enum does not enclose all
/// countries.
/// </summary>
/// <returns>The 2-letter ISO code from system language.</returns>
public static string Get2LetterISOCodeFromSystemLanguage()
{
SystemLanguage lang = Application.systemLanguage;
string res = "EN";
switch (lang)
{
case SystemLanguage.Afrikaans: res = "AF"; break;
case SystemLanguage.Arabic: res = "AR"; break;
case SystemLanguage.Basque: res = "EU"; break;
case SystemLanguage.Belarusian: res = "BY"; break;
case SystemLanguage.Bulgarian: res = "BG"; break;
case SystemLanguage.Catalan: res = "CA"; break;
case SystemLanguage.Chinese: res = "ZH"; break;
case SystemLanguage.ChineseSimplified: res = "ZH"; break;
case SystemLanguage.ChineseTraditional: res = "ZH"; break;
case SystemLanguage.Czech: res = "CS"; break;
case SystemLanguage.Danish: res = "DA"; break;
case SystemLanguage.Dutch: res = "NL"; break;
case SystemLanguage.English: res = "EN"; break;
case SystemLanguage.Estonian: res = "ET"; break;
case SystemLanguage.Faroese: res = "FO"; break;
case SystemLanguage.Finnish: res = "FI"; break;
case SystemLanguage.French: res = "FR"; break;
case SystemLanguage.German: res = "DE"; break;
case SystemLanguage.Greek: res = "EL"; break;
case SystemLanguage.Hebrew: res = "IW"; break;
case SystemLanguage.Hungarian: res = "HU"; break;
case SystemLanguage.Icelandic: res = "IS"; break;
case SystemLanguage.Indonesian: res = "IN"; break;
case SystemLanguage.Italian: res = "IT"; break;
case SystemLanguage.Japanese: res = "JA"; break;
case SystemLanguage.Korean: res = "KO"; break;
case SystemLanguage.Latvian: res = "LV"; break;
case SystemLanguage.Lithuanian: res = "LT"; break;
case SystemLanguage.Norwegian: res = "NO"; break;
case SystemLanguage.Polish: res = "PL"; break;
case SystemLanguage.Portuguese: res = "PT"; break;
case SystemLanguage.Romanian: res = "RO"; break;
case SystemLanguage.Russian: res = "RU"; break;
case SystemLanguage.SerboCroatian: res = "SH"; break;
case SystemLanguage.Slovak: res = "SK"; break;
case SystemLanguage.Slovenian: res = "SL"; break;
case SystemLanguage.Spanish: res = "ES"; break;
case SystemLanguage.Swedish: res = "SV"; break;
case SystemLanguage.Thai: res = "TH"; break;
case SystemLanguage.Turkish: res = "TR"; break;
case SystemLanguage.Ukrainian: res = "UK"; break;
case SystemLanguage.Unknown: res = "EN"; break;
case SystemLanguage.Vietnamese: res = "VI"; break;
}
// Debug.Log ("Lang: " + res);
return res;
}
}
using UnityEngine;
using UnityEngine.UI;
public class I18nTextTranslator : MonoBehaviour
{
public string TextId;
// Use this for initialization
void Start()
{
var text = GetComponent<Text>();
if (text != null)
if(TextId == "ISOCode")
text.text = I18n.GetLanguage();
else
text.text = I18n.Fields[TextId];
}
// Update is called once per frame
void Update()
{
}
}
@R4k4210
Copy link

R4k4210 commented Apr 27, 2018

Thanks for the code, i personally added a Trim() (Ej: Fields.Add(key.Trim(), value.Trim())).
With trim i can organize the key and values on mi txt.

from this:

small.key=small Value !!!
very.large.key=very large value !!

to this:

small.key = small Value !!!
very.large.key = very large value !!

Thanks again!

@davidlamhauge
Copy link

I tried your scripts, and couldn't get it to work.
I guess that is because I use 3Dtext and not 2D.
Will it work on 3D textmeshes, or...
Thanks for your work!

@tguyon
Copy link

tguyon commented Sep 17, 2018

Great, simple and elegant ressource !
and so easy to adapt

@sverveer1984
Copy link

Great Scripts for translating content.
got small question.
can anyone tell me how to attach the language selection to a ui dropdown?
Would be much appreciated!

@danishsshaikh
Copy link

can anyone tell me how to attach the language selection to a ui dropdown?

Could you be a little more specific, so that anyone can look down to the issue more accurately?

@kondratvss
Copy link

Hello, please tell me how to make a language selection via the dropdown?

@Davilarek
Copy link

polish characters not working pls tell me how to have polish characters!

@ditzel
Copy link
Author

ditzel commented Aug 12, 2020

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

@Davilarek
Copy link

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

default font in unity text

@danishsshaikh
Copy link

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

default font in unity text

Arial works fine for me.

@Davilarek
Copy link

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

default font in unity text

Arial works fine for me.

for me it's black-background triangle with ? on center

@Davilarek
Copy link

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

default font in unity text

Arial works fine for me.

for me it's black-background triangle with ? on center

� this

@King-Korol
Copy link

Thanks!

@danishsshaikh
Copy link

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

default font in unity text

Arial works fine for me.

for me it's black-background triangle with ? on center

� this

did you tried putting it in English, and then put the translation of it in Unity?

@Davilarek
Copy link

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

default font in unity text

Arial works fine for me.

for me it's black-background triangle with ? on center

� this

did you tried putting it in English, and then put the translation of it in Unity?

I'm polish, so I did polish game and now I'm translating it to English, but I needed to write into pl.txt all of my polish texts because if polish client has been detected by I18n and pl.txt is empty it gives just blank text fields. But when I wrote polish character in pl.txt it shows this symbol. Ahh yes, when polish character it gives an error about... Dictionary error?

@Mikoai
Copy link

Mikoai commented Nov 21, 2020

polish characters not working pls tell me how to have polish characters!

it depends on the fount you are using

default font in unity text

Arial works fine for me.

for me it's black-background triangle with ? on center

� this

did you tried putting it in English, and then put the translation of it in Unity?

I'm polish, so I did polish game and now I'm translating it to English, but I needed to write into pl.txt all of my polish texts because if polish client has been detected by I18n and pl.txt is empty it gives just blank text fields. But when I wrote polish character in pl.txt it shows this symbol. Ahh yes, when polish character it gives an error about... Dictionary error?

Check source file coding (pl.txt) and make sure it is UTF-8 without BOM.

@Mikoai
Copy link

Mikoai commented Nov 21, 2020

If someone is using TextMeshPro, in I18nTextTranslator.cs you need to add:

using TMPro;

then change:
var text = GetComponent();
to
var text = GetComponent();

and it should be working fine.

@llaagg
Copy link

llaagg commented May 8, 2021

I've added small helper method to use with string.Format()
forked gist

so it can be used with some arguments
hi0=Hi {0}!

    /// <summary>
    /// Helper for string format and translation keys.  
    /// </summary>
    /// <param name="key">as in translation file</param>
    /// <param name="args">optional parameters to be put in output if they are provided in tranlstion file for ex.: hi0=Hi {0}!</param>
    /// <returns>translated string based </returns>
    public static string T(string key, params object [] args)
    {
        string kText = Fields.ContainsKey(key) ? Fields[key] : "( "+ key +")";
        return String.Format(kText, args);
    }

@fgsoftware1
Copy link

fgsoftware1 commented Dec 29, 2021

cannot use GetSysteLanguage from monobehaviour constructor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment