facebook twitter hatena line email

「Unity/多言語化」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(ページの作成:「==ダウンロード== https://learn.unity.com/tutorial/recorded-video-session-localization-tools/?tab=detail#5c7f8528edbc2a002053b671 <pre> LocalizationData.cs Localizat...」)
 
(日本語以外のとき翻訳)
(同じ利用者による、間の30版が非表示)
行1: 行1:
 
==ダウンロード==
 
==ダウンロード==
 +
AssetStoreではなく以下からDLする。
 +
 
https://learn.unity.com/tutorial/recorded-video-session-localization-tools/?tab=detail#5c7f8528edbc2a002053b671
 
https://learn.unity.com/tutorial/recorded-video-session-localization-tools/?tab=detail#5c7f8528edbc2a002053b671
 
<pre>
 
<pre>
行10: 行12:
  
 
==翻訳ファイルサンプル==
 
==翻訳ファイルサンプル==
Assets/StreamingAssets/localizedText_ja.json
+
AndroidでStreamingAssetsが取得できなかったので、Resourcesに入れた。
 +
 
 +
Assets/Resources/Localization/ja.json
 
<pre>
 
<pre>
 
{
 
{
行19: 行23:
 
}
 
}
 
</pre>
 
</pre>
Assets/StreamingAssets/localizedText_en.json
+
Assets/Resources/Localization/en.json
 
<pre>
 
<pre>
 
{
 
{
行28: 行32:
 
}
 
}
 
</pre>
 
</pre>
 +
 +
==上記DLしたファイル設定==
 +
端末言語を自動で判定し翻訳するようにカスタマイズしてあります。
 +
指定することもできます。(下の項目でやり方記載)
 +
 +
LocalizationData.cs
 +
<pre>
 +
[System.Serializable]
 +
public class LocalizationData
 +
{
 +
    public LocalizationItem[] items;
 +
}
 +
 +
[System.Serializable]
 +
public class LocalizationItem
 +
{
 +
    public string key;
 +
    public string value;
 +
}
 +
</pre>
 +
LocalizationManager.cs
 +
<pre>
 +
using System.Collections;
 +
using System.Collections.Generic;
 +
using UnityEngine;
 +
using System.IO;
 +
 +
public class LocalizationManager : MonoBehaviour {
 +
 +
    public static LocalizationManager instance;
 +
 +
    private Dictionary<string, string> localizedText;
 +
    private bool isReady = false;
 +
    private string missingTextString = "Localized text not found";
 +
    private string lang = "";
 +
 +
    // Use this for initialization
 +
    void Awake ()
 +
    {
 +
        if (instance == null) {
 +
            instance = this;
 +
        } else if (instance != this)
 +
        {
 +
            Destroy (gameObject);
 +
        }
 +
        DontDestroyOnLoad (gameObject);
 +
    }
 +
    public void LoadLocalizedText(string fileName)
 +
    {
 +
        LoadAsset(fileName);
 +
    }
 +
 +
    public void LoadAsset(string fileName)
 +
    {
 +
        string filePath = Path.Combine("Localization", fileName);
 +
        filePath = filePath.Replace(".json", "");
 +
        string dataAsJson = Resources.Load<TextAsset>(filePath).text;
 +
        LoadJson(dataAsJson);
 +
    }
 +
    private void LoadJson(string dataAsJson)
 +
    {
 +
        localizedText = new Dictionary<string, string>();
 +
        LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);
 +
 +
        for (int i = 0; i < loadedData.items.Length; i++)
 +
        {
 +
            localizedText.Add(loadedData.items[i].key, loadedData.items[i].value);
 +
        }
 +
 +
        Debug.Log("Data loaded, dictionary contains: " + localizedText.Count + " entries");
 +
        isReady = true;
 +
    }
 +
 +
    public string GetLocalizedValue(string key)
 +
    {
 +
        string result = missingTextString;
 +
        if (localizedText.ContainsKey (key))
 +
        {
 +
            result = localizedText [key];
 +
        }
 +
        return result;
 +
    }
 +
 +
    public bool GetIsReady()
 +
    {
 +
        return isReady;
 +
    }
 +
 +
    public void LoadLanguageTerminal()
 +
    {
 +
        var language = Application.systemLanguage;
 +
       
 +
        if (language == SystemLanguage.Japanese)
 +
        {
 +
            lang = "ja";
 +
        }
 +
        else if (language == SystemLanguage.ChineseSimplified)
 +
        {
 +
            // 簡体字
 +
            lang = "zh-CN";
 +
        }
 +
        else if (language == SystemLanguage.ChineseTraditional)
 +
        {
 +
            // 繁体字
 +
            lang = "zh-TW";
 +
        }
 +
        else if (language == SystemLanguage.Vietnamese)
 +
        {
 +
            lang = "vi";
 +
        }
 +
        else if (language == SystemLanguage.Dutch)
 +
        {
 +
            lang = "de";
 +
        }
 +
        else if (language == SystemLanguage.Korean)
 +
        {
 +
            lang = "ko";
 +
        }
 +
        else if (language == SystemLanguage.Spanish)
 +
        {
 +
            lang = "es";
 +
        }
 +
        else
 +
        {
 +
            lang = "en";
 +
        }
 +
        LoadLocalizedText(lang + ".json");
 +
    }
 +
    public void LoadLanguage(string lang)
 +
    {
 +
        this.lang = lang;
 +
        if (!lang.Equals("terminal"))
 +
        {
 +
            LoadLocalizedText(lang + ".json");
 +
        }
 +
    }
 +
    public string GetLanguage()
 +
    {
 +
        return lang;
 +
    }
 +
}
 +
</pre>
 +
LocalizedText.cs
 +
<pre>
 +
using System.Collections.Generic;
 +
using UnityEngine;
 +
using UnityEngine.UI;
 +
 +
public class LocalizedText : MonoBehaviour {
 +
 +
    public string key;
 +
 +
    void Start ()
 +
    {
 +
        Text text = GetComponent<Text> ();
 +
        LocalizationManager manager = LocalizationManager.instance;
 +
        if (manager == null)
 +
        {
 +
            return;
 +
        }
 +
        string str = manager.GetLocalizedValue(key);
 +
        if (str == null)
 +
        {
 +
            return;
 +
        }
 +
        Debug.Log("LocalizedText key=" + key);
 +
        text.text = str;
 +
    }
 +
 +
}
 +
</pre>
 +
LocalizedTextEditor.cs
 +
<pre>
 +
using System.Collections;
 +
using System.Collections.Generic;
 +
using UnityEngine;
 +
using UnityEditor;
 +
using System.IO;
 +
 +
public class LocalizedTextEditor : EditorWindow
 +
{
 +
    public LocalizationData localizationData;
 +
 +
    [MenuItem ("Window/Localized Text Editor")]
 +
    static void Init()
 +
    {
 +
        EditorWindow.GetWindow (typeof(LocalizedTextEditor)).Show ();
 +
    }
 +
 +
    private void OnGUI()
 +
    {
 +
        if (localizationData != null)
 +
        {
 +
            SerializedObject serializedObject = new SerializedObject (this);
 +
            SerializedProperty serializedProperty = serializedObject.FindProperty ("localizationData");
 +
            EditorGUILayout.PropertyField (serializedProperty, true);
 +
            serializedObject.ApplyModifiedProperties ();
 +
 +
            if (GUILayout.Button ("Save data"))
 +
            {
 +
                SaveGameData ();
 +
            }
 +
        }
 +
 +
        if (GUILayout.Button ("Load data"))
 +
        {
 +
            LoadGameData ();
 +
        }
 +
 +
        if (GUILayout.Button ("Create new data"))
 +
        {
 +
            CreateNewData ();
 +
        }
 +
    }
 +
 +
    private void LoadGameData()
 +
    {
 +
        string filePath = EditorUtility.OpenFilePanel ("Select localization data file", Application.streamingAssetsPath, "json");
 +
 +
        if (!string.IsNullOrEmpty (filePath))
 +
        {
 +
            string dataAsJson = File.ReadAllText (filePath);
 +
            localizationData = JsonUtility.FromJson<LocalizationData> (dataAsJson);
 +
        }
 +
    }
 +
 +
    private void SaveGameData()
 +
    {
 +
        string filePath = EditorUtility.SaveFilePanel ("Save localization data file", Application.streamingAssetsPath, "", "json");
 +
 +
        if (!string.IsNullOrEmpty(filePath))
 +
            {
 +
                string dataAsJson = JsonUtility.ToJson(localizationData);
 +
                File.WriteAllText (filePath, dataAsJson);
 +
            }
 +
    }
 +
 +
    private void CreateNewData()
 +
    {
 +
        localizationData = new LocalizationData ();
 +
    }
 +
}
 +
</pre>
 +
 +
StartupManager.cs
 +
<pre>
 +
using System.Collections;
 +
using System.Collections.Generic;
 +
using UnityEngine;
 +
using UnityEngine.SceneManagement;
 +
 +
[DefaultExecutionOrder(-1)]
 +
public class StartupManager : MonoBehaviour {
 +
 +
    // Use this for initialization
 +
    private IEnumerator Start ()
 +
    {
 +
        LocalizationManager.instance.LoadLanguageTerminal();
 +
        while (!LocalizationManager.instance.GetIsReady ())
 +
        {
 +
            yield return null;
 +
        }
 +
    }
 +
 +
}
 +
</pre>
 +
 +
 +
==設置方法==
 +
#起動sceneに適当に空のGameObjectを作る
 +
#そこにLocalizationManagerとStartupManagerを貼り付ける
 +
#翻訳したいTextオブジェクトにAddComponentsでLocalizedTextを選択しKeyにjsonのkeyに指定したtitle1などと入れる。
 +
 +
無事翻訳できた。
 +
 +
==初回sceneで翻訳されない場合==
 +
StartupManagerのクラスの上に[DefaultExecutionOrder(-1)]を記述して実行順をどのsceneよりも早くロードするように
 +
 +
[DefaultExecutionOrder(-1)]
 +
public class StartupManager : MonoBehaviour {
 +
 +
==手動で切り替え==
 +
手動でやりたい場合は以下のようにすると良い。
 +
LocalizationManager.instance.LoadLanguage("ja");
 +
 +
==Scriptで文言を出す==
 +
LocalizationManager.instance.GetLocalizedValue("welcome")
 +
 +
==日本語以外のとき翻訳==
 +
<pre>
 +
LocalizationManager localizationManager = LocalizationManager.instance;
 +
if (localizationManager != null)
 +
{
 +
  if (!localizationManager.GetLanguage().Equals("ja"))
 +
  {
 +
    GameObject.Find("HelloButton/Text").GetComponent<Text>().text = localizationManager.GetLocalizedValue("hello");
 +
    }
 +
}
 +
</pre>
 +
 +
==Androidのアプリタイトルの多言語化==
 +
Assets/Plugins/Android/res/values-ja/strings.xml
 +
<pre>
 +
<?xml version="1.0" encoding="utf-8"?>
 +
<resources>
 +
    <string name="app_name">タイトル1</string>
 +
</resources>
 +
</pre>
 +
 +
==Androidの場合は読み込めない==
 +
StreamingAssetsではAndroidの場合は読み込めないのでResourcesに移動してある
 +
 +
参考:https://teratail.com/questions/169361
 +
 
==参考==
 
==参考==
 
https://www.growthsoftware.jp/unity-multilang/
 
https://www.growthsoftware.jp/unity-multilang/
  
 
https://qiita.com/chocho/items/c32e75bf498d8beec08f
 
https://qiita.com/chocho/items/c32e75bf498d8beec08f

2020年6月17日 (水) 11:49時点における版

ダウンロード

AssetStoreではなく以下からDLする。

https://learn.unity.com/tutorial/recorded-video-session-localization-tools/?tab=detail#5c7f8528edbc2a002053b671

LocalizationData.cs
LocalizationManager.cs
StartupManager.cs
LocalizedText.cs
LocalizedTextEditor.cs

翻訳ファイルサンプル

AndroidでStreamingAssetsが取得できなかったので、Resourcesに入れた。

Assets/Resources/Localization/ja.json

{
  "items":[
    {"key":"title","value":"タイトル1"},
    {"key":"edit","value":"編集1"}
  ]
}

Assets/Resources/Localization/en.json

{
  "items":[
    {"key":"title","value":"title1"},
    {"key":"edit","value":"edit1"}
   ]
}

上記DLしたファイル設定

端末言語を自動で判定し翻訳するようにカスタマイズしてあります。 指定することもできます。(下の項目でやり方記載)

LocalizationData.cs

[System.Serializable]
public class LocalizationData
{
    public LocalizationItem[] items;
}

[System.Serializable]
public class LocalizationItem
{
    public string key;
    public string value;
}

LocalizationManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class LocalizationManager : MonoBehaviour {

    public static LocalizationManager instance;

    private Dictionary<string, string> localizedText;
    private bool isReady = false;
    private string missingTextString = "Localized text not found";
    private string lang = "";

    // Use this for initialization
    void Awake () 
    {
        if (instance == null) {
            instance = this;
        } else if (instance != this)
        {
            Destroy (gameObject);
        }
        DontDestroyOnLoad (gameObject);
    }
    public void LoadLocalizedText(string fileName)
    {
        LoadAsset(fileName);
    }

    public void LoadAsset(string fileName)
    {
        string filePath = Path.Combine("Localization", fileName);
        filePath = filePath.Replace(".json", "");
        string dataAsJson = Resources.Load<TextAsset>(filePath).text;
        LoadJson(dataAsJson);
    }
    private void LoadJson(string dataAsJson)
    {
        localizedText = new Dictionary<string, string>();
        LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);

        for (int i = 0; i < loadedData.items.Length; i++)
        {
            localizedText.Add(loadedData.items[i].key, loadedData.items[i].value);
        }

        Debug.Log("Data loaded, dictionary contains: " + localizedText.Count + " entries");
        isReady = true;
    }

    public string GetLocalizedValue(string key)
    {
        string result = missingTextString;
        if (localizedText.ContainsKey (key)) 
        {
            result = localizedText [key];
        }
        return result;
    }

    public bool GetIsReady()
    {
        return isReady;
    }

    public void LoadLanguageTerminal()
    {
        var language = Application.systemLanguage;
        
        if (language == SystemLanguage.Japanese)
        {
            lang = "ja";
        }
        else if (language == SystemLanguage.ChineseSimplified)
        {
            // 簡体字
            lang = "zh-CN";
        }
        else if (language == SystemLanguage.ChineseTraditional)
        {
            // 繁体字
            lang = "zh-TW";
        }
        else if (language == SystemLanguage.Vietnamese)
        {
            lang = "vi";
        }
        else if (language == SystemLanguage.Dutch)
        {
            lang = "de";
        }
        else if (language == SystemLanguage.Korean)
        {
            lang = "ko";
        }
        else if (language == SystemLanguage.Spanish)
        {
            lang = "es";
        }
        else
        {
            lang = "en";
        }
        LoadLocalizedText(lang + ".json");
    }
    public void LoadLanguage(string lang)
    {
        this.lang = lang;
        if (!lang.Equals("terminal"))
        {
            LoadLocalizedText(lang + ".json");
        }
    }
    public string GetLanguage()
    {
        return lang;
    }
}

LocalizedText.cs

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

public class LocalizedText : MonoBehaviour {

    public string key;

    void Start () 
    {
        Text text = GetComponent<Text> ();
        LocalizationManager manager = LocalizationManager.instance;
        if (manager == null)
        {
            return;
        }
        string str = manager.GetLocalizedValue(key);
        if (str == null)
        {
            return;
        }
        Debug.Log("LocalizedText key=" + key);
        text.text = str;
    }

}

LocalizedTextEditor.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;

public class LocalizedTextEditor : EditorWindow
{
    public LocalizationData localizationData;

    [MenuItem ("Window/Localized Text Editor")]
    static void Init()
    {
        EditorWindow.GetWindow (typeof(LocalizedTextEditor)).Show ();
    }

    private void OnGUI()
    {
        if (localizationData != null) 
        {
            SerializedObject serializedObject = new SerializedObject (this);
            SerializedProperty serializedProperty = serializedObject.FindProperty ("localizationData");
            EditorGUILayout.PropertyField (serializedProperty, true);
            serializedObject.ApplyModifiedProperties ();

            if (GUILayout.Button ("Save data")) 
            {
                SaveGameData ();
            }
        }

        if (GUILayout.Button ("Load data")) 
        {
            LoadGameData ();
        }

        if (GUILayout.Button ("Create new data")) 
        {
            CreateNewData ();
        }
    }

    private void LoadGameData()
    {
        string filePath = EditorUtility.OpenFilePanel ("Select localization data file", Application.streamingAssetsPath, "json");

        if (!string.IsNullOrEmpty (filePath)) 
        {
            string dataAsJson = File.ReadAllText (filePath);
            localizationData = JsonUtility.FromJson<LocalizationData> (dataAsJson);
        }
    }

    private void SaveGameData()
    {
        string filePath = EditorUtility.SaveFilePanel ("Save localization data file", Application.streamingAssetsPath, "", "json");

        if (!string.IsNullOrEmpty(filePath))
            {
                string dataAsJson = JsonUtility.ToJson(localizationData);
                File.WriteAllText (filePath, dataAsJson);
            }
    }

    private void CreateNewData()
    {
        localizationData = new LocalizationData ();
    }
}

StartupManager.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

[DefaultExecutionOrder(-1)]
public class StartupManager : MonoBehaviour {

    // Use this for initialization
    private IEnumerator Start () 
    {
        LocalizationManager.instance.LoadLanguageTerminal();
        while (!LocalizationManager.instance.GetIsReady ()) 
        {
            yield return null;
        }
    }

}


設置方法

  1. 起動sceneに適当に空のGameObjectを作る
  2. そこにLocalizationManagerとStartupManagerを貼り付ける
  3. 翻訳したいTextオブジェクトにAddComponentsでLocalizedTextを選択しKeyにjsonのkeyに指定したtitle1などと入れる。

無事翻訳できた。

初回sceneで翻訳されない場合

StartupManagerのクラスの上に[DefaultExecutionOrder(-1)]を記述して実行順をどのsceneよりも早くロードするように

[DefaultExecutionOrder(-1)]
public class StartupManager : MonoBehaviour {

手動で切り替え

手動でやりたい場合は以下のようにすると良い。

LocalizationManager.instance.LoadLanguage("ja");

Scriptで文言を出す

LocalizationManager.instance.GetLocalizedValue("welcome")

日本語以外のとき翻訳

LocalizationManager localizationManager = LocalizationManager.instance;
if (localizationManager != null)
{
   if (!localizationManager.GetLanguage().Equals("ja"))
   {
     GameObject.Find("HelloButton/Text").GetComponent<Text>().text = localizationManager.GetLocalizedValue("hello");
    }
}

Androidのアプリタイトルの多言語化

Assets/Plugins/Android/res/values-ja/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">タイトル1</string>
</resources>

Androidの場合は読み込めない

StreamingAssetsではAndroidの場合は読み込めないのでResourcesに移動してある

参考:https://teratail.com/questions/169361

参考

https://www.growthsoftware.jp/unity-multilang/

https://qiita.com/chocho/items/c32e75bf498d8beec08f