Mini Tutorial: How to localize your Unity game to Chinese? (Step 1)

UPDATE: Fixed the link to FontForge Installer http://fontforge.github.io/en-US/downloads/mac/

I get a lot of interesting answers to problems on the Unity forums, even if it’s in the Showcase threads.

Like for example, on how to localize your Unity games, particularly. In case you didn’t know, there are sooo much Chinese characters, so much that it couldn’t possibly fit in a 2048×2048 font texture. So the solution to that according to Aby Escape’s (do check out their game on iTunes, it’s free and looks pretty fun: http://itunes.apple.com/app/id513265471) Juan Luis (http://forum.unity3d.com/threads/133731-Aby-Escape-iOS-Free-Game?p=924644&viewfull=1#post924644):

Solution:
-Take a font file (ttf) and remove all the characters that you don´t use on your game.

For this solution there are a link on unifyComunity: http://www.unifycommunity.com/wiki/i…_TrueType_font

But this is a partial solution, because for me, if I select CJK characters selecting by script, there are missings character on my game.

So I want to select ONLY the characters that my game using.

You can check out his code in this forum thread (http://forum.unity3d.com/threads/133731-Aby-Escape-iOS-Free-Game?p=924644&viewfull=1#post924644).

But his script is in Javascript, and prints output on the console, according to Juan Luis there are limits with the output of the unity Console, so you can split the string, or print it on a file.

So I wrote an Unity Editor script based on his that accepts a Text file that contains all the characters that you’d need in your game, and then it outputs a Text file containing a script that you can just copy paste in FontForge.

ConvertTextToUnicode.cs

using UnityEngine;
using UnityEditor;
using System.Collections;

public class ConvertTextToUnicode: EditorWindow
{   
    TextAsset inputText;

    [MenuItem (“Project Tools/Convert Text to Unicode”)]
    static void Init ()
    {    ConvertTextToUnicode window = (ConvertTextToUnicode)EditorWindow.GetWindow (typeof (ConvertTextToUnicode));
    }

    void OnGUI ()
    {    inputText = EditorGUILayout.ObjectField(“Input Text”, inputText, typeof(TextAsset)) as TextAsset;

        if(GUILayout.Button(“Convert”))
        {    Convert();
        }
    }

    void Convert()
    {    string inputTextString = inputText.text;

        string[] inputTextArr = inputTextString.Split(‘n’);

        string finalScript = “”;

        for(int i=0; i< inputTextArr.Length; i++)
        {    string script = “SelectMoreSingletons(“;

            string line = inputTextArr[i];

            for(int j=0; j < line.Length; j++)
            {    string unicode = System.Convert.ToInt32(line[j]).ToString(“X”);

                   if(unicode.Length == 1)
                    unicode = “U+000” + unicode;
                else if(unicode.Length == 2)
                    unicode = “U+00” + unicode;
                else if(unicode.Length == 3)
                    unicode = “U+0” + unicode;
                else if(unicode.Length == 4)
                    unicode = “U+” + unicode;

                if(!script.Contains(unicode) && !finalScript.Contains(unicode))
                {    script = script + “"”+ unicode + “"” +  “,” ;
                }

                   if((j+1)%10 == 0)
                {    script =  script + “"” + “U+0020");”;

                    if(i == 0)
                    {    finalScript = script;
                    }    else
                    {    finalScript = finalScript + “n”+  script;
                    }

                       script = “SelectMoreSingletons(“;
                }
            }

            script =  script + “"” + “U+0020");”;
            finalScript = finalScript + “n”+  script;
        }

        System.IO.File.WriteAllText(“Assets/”+inputText.name+”Converted.txt”, finalScript);
    }
}

Place this script in the Assets/Editor folder of your Unity project.

The Unity Wiki (http://wiki.unity3d.com/index.php?title=Create_a_new_TrueType_font_using_a_subset_of_characters_from_an_existing_TrueType_font) has very detailed instructions for the rest of the steps.

Step 1 is Download and Install FontForge (http://fontforge.sourceforge.net/), but FontForge no longer provides binary packages. A little Google-ing found me this link: http://fontforge.github.io/en-US/downloads/mac/. The site is still under construction it seems, but the linked FontForge Beta Package works.

Step 2 is Get a unicode font, e.g. Arial Unicode MS. The ArialUni.ttf font can be found in Windows in C:WINDOWSFont, or if you’re on a Mac, go to Font Book, select the font you want, right click and then Show in Finder.

And then follow the rest of the steps ish for extracting a specific subrange of characters.

1. Open the font in FontForge

Instead of their step 2 and 3, go to File and then Execute Script.

image

A window with a text field is going to pop up, just copy and paste your converted characters script in there and click OK.

image

And then go back to following the instructions on Unity Wiki:

4. Invert your selection by going to Edit->Select->Invert Selection

5. Remove these unwanted symbols by going to Encoding->Detach & Remove Glyphs. This may take some time – but when it is finished you will notice that all the highlighted font cells have now been crossed out.

Operation in progress example (this may take sometime, try not to touch anything FontForge can be a bit unstable):
HarryTuttleFF1.png

Operation complete example, all the selected symbols have been replaced with crosses:
HarryTuttleFF2.png

You may find some of your character cells have blue in them, I don’t know what this means but it has not caused me any problems:
HarryTuttleFF3.png

6. Compact your new font to only the useable symbols by going to Encoding->Compact.
Compacted font example:
HarryTuttleFF4.png

7. Generate the TTF font by going to File->Generate Fonts.
The only option I change is the export type to TrueType.
HarryTuttleFF5.png
8. Import into Unity, sacrifice something to the God of FontForge and enjoy.

Yes, sacrificing to the God of FontForge is a must.

And that’s it, you have a new font with Chinese characters that fits into a 2048×2048 font texture.

Other tips: How to find out the language of your iPhone when using Unity?, because Unity can’t seem to differentiate Traditional Chinese from Simplified Chinese (yes, there is a difference).

Advertisements

How to find out the language of your iPhone when using Unity?

For localizations and stuff, you know? Like say if you want your game to support different languages like English, Chinese, Japanese and stuff.

There’s Application.systemLanguage (I think it’s supported on iOS now, since I tested it on my device and it returns the correct language). It supports these languages: Afrikaans, Arabic, Basque, Belarusian, Bulgarian, Catalan, Chinese, Czech, Danish, Dutch, English, Estonian, Faroese, Finnish, French, German, Greek, Hebrew, Hugarian, Icelandic, Indonesian, Italian, Japanese, Korean, Latvian, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, Serbo-Croatian, Slovak, Slovenian, Spanish, Swedish, Thai, Turkish, Ukrainian, Vietnamese and Hungarian. And if your selected language is not on that list, it returns: Unknown. So if the language that you want to support is on that list, you don’t have to read the rest of this post. Application.systemLanguage is all you need.

But, but, if you are like me (Taiwanese/Chinese), you might need to support not just Chinese, but Simplified and Traditional Chinese (there is a difference), unfortunately Application.systemLanguage, doesn’t know that difference. But the iOS SDK does.

So I want to use iOS SDK’s way of identifying languages using the code:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [defaults objectForKey:@”AppleLanguages”];
    NSString *currentLanguage = [languages objectAtIndex:0];

I then save the current language to NSUserDefaults:

[[NSUserDefaults standardUserDefaults] setObject:currentLanguage forKey:@”language”];
[[NSUserDefaults standardUserDefaults] synchronize];

So I can access it in Unity, using PlayerPrefs:

PlayerPrefs.GetString(“language”)

So here’s the thing the iOS code needs to be added in AppController.mm that’s generated when you build Unity iOS.

I added that part before Unity gets called ([self startUnity:application]) inapplication didFinishLaunchingWithOptions.

But, but, every time you build, AppController.mm gets overwritten, so, so, what now?

After Unity 3.5, all you have to do is to drag and drop your AppController.mm file into Plugins/iOS folder inside Unity Assets folder and that copy will automatically overwrite whatever that is generated.

And that is it! 🙂