くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Unity×Androidで多言語化・国際化したときにやった3つのこと

ひさびさにUnityでAndroidアプリを作ってみました!

拙作、初の横スクロールアクション「あざらしロジック」!(あざらしロジック - Google Play の Android アプリ)

f:id:wannabe-jellyfish:20170128222935p:plain

www.youtube.com

その際にいろいろやったので、忘れないための備忘録φ(..)メモメモ

日・英・中・韓に対応したので、その時の話

どこの記事かは忘れてしまったのだけれど。。。

ゲームで国際化・多言語化する場合は、日・英・中・韓に対応するのがよいらしい。

中国・韓国はアルファベット表記に馴染みがないので、日・英だけではだめなのだとか。

とりあえず、やってみようと思い、以下のことをしてみた。

  1. ゲーム中の文言/画像を国際化
  2. アプリ名を国際化
  3. アプリストアの説明文を国際化

ゲーム中の文言/画像を国際化(Editor拡張)

以下の記事を見つけて、「いいな!」と思ったので、参考にしてEditor拡張してみた。 lightgive.hatenadiary.jp

こっちが、Image版(LocalizeUIImage.cs)で、

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
#endif

public class LocalizeUIImage : MonoBehaviour {

    [SerializeField] Sprite imageEn;
    [SerializeField] Sprite imageJp;
    [SerializeField] Sprite imageZh;
    [SerializeField] Sprite imageZhCn;
    [SerializeField] Sprite imageZhTw;
    [SerializeField] Sprite imageKo;

    void Awake() {
        Dictionary<SystemLanguage, Sprite>  dict = new Dictionary<SystemLanguage, Sprite>() {
            { SystemLanguage.English, imageEn},
            { SystemLanguage.Japanese, imageJp},
            { SystemLanguage.Chinese, imageZh},
            { SystemLanguage.ChineseSimplified, imageZhCn},
            { SystemLanguage.ChineseTraditional, imageZhTw},
            { SystemLanguage.Korean, imageKo},
        };

        //Change
        SystemLanguage lang = Application.systemLanguage;
        Image mImage = GetComponent<Image>();
        mImage.sprite = dict.ContainsKey(lang) ? dict[lang] : dict[SystemLanguage.English];
    }
}

#if UNITY_EDITOR
[CustomEditor(typeof(LocalizeUIImage))]
[CanEditMultipleObjects]
public class LocalizeEditorImage : Editor {

    SerializedProperty propEn;
    SerializedProperty propJp;
    SerializedProperty propZh;
    SerializedProperty propZhCn;
    SerializedProperty propZhTw;
    SerializedProperty propKo;

    void OnEnable() {
        propEn = serializedObject.FindProperty("imageEn");
        propJp = serializedObject.FindProperty("imageJp");
        propZh = serializedObject.FindProperty("imageZh");
        propZhCn = serializedObject.FindProperty("imageZhCn");
        propZhTw = serializedObject.FindProperty("imageZhTw");
        propKo = serializedObject.FindProperty("imageKo");
    }

    public override void OnInspectorGUI() {
        serializedObject.Update();

        CreateUI("English", propEn, true);
        CreateUI("Japanese", propJp, true);
        CreateUI("Chainese", propZh, true);
        CreateUI("Chainese(Simplified)", propZhCn, true);
        CreateUI("Chainese(Traditional)", propZhTw, true);
        CreateUI("Korean", propKo, false);

        serializedObject.ApplyModifiedProperties();
    }

    private void CreateUI(string label, SerializedProperty prop, bool addSpace) {
        EditorGUILayout.LabelField(label, EditorStyles.boldLabel);
        prop.objectReferenceValue = (Sprite) EditorGUILayout.ObjectField(prop.objectReferenceValue, typeof(Sprite), true);
        if(addSpace) EditorGUILayout.Space();
    }
}
#endif

こっちが、Text版(LocalizeUITextArea.cs)

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
#endif

public class LocalizeUITextArea : MonoBehaviour {

    [SerializeField] string strEn;
    [SerializeField] string strJp;
    [SerializeField] string strZh;
    [SerializeField] string strZhCn;
    [SerializeField] string strZhTw;
    [SerializeField] string strKo;

    void Awake() {
        Dictionary<SystemLanguage, string> dict = new Dictionary<SystemLanguage, string>() {
            { SystemLanguage.English, strEn},
            { SystemLanguage.Japanese, strJp},
            { SystemLanguage.Chinese, strZh},
            { SystemLanguage.ChineseSimplified, strZhCn},
            { SystemLanguage.ChineseTraditional, strZhTw},
            { SystemLanguage.Korean, strKo},
        };

        //Change
        SystemLanguage lang = Application.systemLanguage;
        Text mText = GetComponent<Text>();
        mText.text = dict.ContainsKey(lang) ? dict[lang] : dict[SystemLanguage.English];
    }
}

#if UNITY_EDITOR
[CustomEditor(typeof(LocalizeUITextArea))]
[CanEditMultipleObjects]
public class LocalizeEditorTextArea : Editor {

    SerializedProperty propEn;
    SerializedProperty propJp;
    SerializedProperty propZh;
    SerializedProperty propZhCn;
    SerializedProperty propZhTw;
    SerializedProperty propKo;

    void OnEnable() {
        propEn = serializedObject.FindProperty("strEn");
        propJp = serializedObject.FindProperty("strJp");
        propZh = serializedObject.FindProperty("strZh");
        propZhCn = serializedObject.FindProperty("strZhCn");
        propZhTw = serializedObject.FindProperty("strZhTw");
        propKo = serializedObject.FindProperty("strKo");
    }

    public override void OnInspectorGUI() {
        serializedObject.Update();

        CreateUI("English", propEn, true);
        CreateUI("Japanese", propJp, true);
        CreateUI("Chainese", propZh, true);
        CreateUI("Chainese(Simplified)", propZhCn, true);
        CreateUI("Chainese(Traditional)", propZhTw, true);
        CreateUI("Korean", propKo, false);

        serializedObject.ApplyModifiedProperties();
    }

    private void CreateUI(string label, SerializedProperty prop, bool addSpace) {
        EditorGUILayout.LabelField(label, EditorStyles.boldLabel);
        prop.stringValue = EditorGUILayout.TextArea(prop.stringValue);
        if(addSpace) EditorGUILayout.Space();
    }
}
#endif

Unity上ではこんな感じ

それぞれをuGUIのText/Imageにアタッチする感じに使う。

f:id:wannabe-jellyfish:20170129010940p:plain

スクリプト上に項目が出てくるので、それぞれ言語で表示してほしいものを設定

あとは、実行すると、言語に応じて設定を表示が変わる!

f:id:wannabe-jellyfish:20170129011133p:plain

※例だと、日本語環境で実行しているので、「Japanese」の設定値になってます。

アプリ名を国際化

アプリ名については、通常のAndoridと同じように「values-xx」を作成する感じ。

ただ、デフォルトのアプリ名については、Unity上で設定が必要なので注意!

techbooster.org

必要なres/values-xxを一括で作成するスクリプトはこちら

  • ./createStringXml.shとすると、その場に、
  • ./createStringXml.sh NewProjectとすると、「NewProject」配下に

必要なファイルを作成してくれるので、あとは編集するだけ。

#!/bin/bash


## set root path
root=$1
test "$root" = "" && root='.'


## create string.xml
langs='
en
ja
zh
zh-rHK
zh-rTW
ko
'

for l in ${langs}; do
  dir=${root}/Assets/Plugins/Android/res/values-${l}
  mkdir -v -p ${dir}
  cat <<EOS > ${dir}/string.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- <string name="app_name">AppName</string> -->
</resources>
EOS
done

アプリストアの説明文を国際化(Google DocsスプレッドシートGoogle翻訳)

以下の記事で、GoogleDocのスプレットシートに、Google翻訳を呼び出す関数が用意されているらしい! toomva.blog60.fc2.com

GOOGLETRANSLATE(値,ソース言語,ターゲット言語)

こんな感じで使うらしい。

=GOOGLETRANSLATE($A2,“ja”,“en”)

言語は、

言語 記号
日本語 ja
英語 en
中国語(簡体) zh
中国語(簡体) zh-CN
中国語(繁体) zh-TW
韓国語 ko-KR

日本語を書けば、一括で置換できるので、あとは、コピペ。

※本当はちゃんと見ないといけないけれど、わからないので、Google翻訳任せ。。。

以上!!

参考にしたサイト様