「Unity/多言語化」の版間の差分
提供: 初心者エンジニアの簡易メモ
(→日本語以外のとき翻訳) |
|||
(同じ利用者による、間の22版が非表示) | |||
行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/ | + | AndroidでStreamingAssetsが取得できなかったので、Resourcesに入れた。 |
+ | |||
+ | Assets/Resources/Localization/ja.json | ||
<pre> | <pre> | ||
{ | { | ||
行19: | 行23: | ||
} | } | ||
</pre> | </pre> | ||
− | Assets/ | + | Assets/Resources/Localization/en.json |
<pre> | <pre> | ||
{ | { | ||
行29: | 行33: | ||
</pre> | </pre> | ||
− | == | + | ==上記DLしたファイル設定== |
+ | 端末言語を自動で判定し翻訳するようにカスタマイズしてあります。 | ||
+ | 指定することもできます。(下の項目でやり方記載) | ||
+ | |||
LocalizationData.cs | LocalizationData.cs | ||
<pre> | <pre> | ||
行59: | 行66: | ||
private bool isReady = false; | private bool isReady = false; | ||
private string missingTextString = "Localized text not found"; | private string missingTextString = "Localized text not found"; | ||
+ | private string lang = ""; | ||
// Use this for initialization | // Use this for initialization | ||
行73: | 行81: | ||
public void LoadLocalizedText(string fileName) | 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; | isReady = true; | ||
} | } | ||
+ | |||
public string GetLocalizedValue(string key) | public string GetLocalizedValue(string key) | ||
{ | { | ||
行105: | 行119: | ||
return isReady; | return isReady; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | public | + | 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> | </pre> | ||
行230: | 行275: | ||
} | } | ||
</pre> | </pre> | ||
− | + | ||
+ | StartupManager.cs | ||
<pre> | <pre> | ||
using System.Collections; | using System.Collections; | ||
+ | using System.Collections.Generic; | ||
using UnityEngine; | using UnityEngine; | ||
+ | using UnityEngine.SceneManagement; | ||
[DefaultExecutionOrder(-1)] | [DefaultExecutionOrder(-1)] | ||
− | public class | + | public class StartupManager : MonoBehaviour { |
− | { | + | |
− | IEnumerator Start() | + | // Use this for initialization |
+ | private IEnumerator Start () | ||
{ | { | ||
− | + | LocalizationManager.instance.LoadLanguageTerminal(); | |
− | + | while (!LocalizationManager.instance.GetIsReady ()) | |
− | + | ||
{ | { | ||
− | + | yield return null; | |
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
+ | |||
} | } | ||
</pre> | </pre> | ||
+ | |||
+ | |||
==設置方法== | ==設置方法== | ||
#起動sceneに適当に空のGameObjectを作る | #起動sceneに適当に空のGameObjectを作る | ||
− | # | + | #そこにLocalizationManagerとStartupManagerを貼り付ける |
#翻訳したいTextオブジェクトにAddComponentsでLocalizedTextを選択しKeyにjsonのkeyに指定したtitle1などと入れる。 | #翻訳したい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 | ||
==参考== | ==参考== |
2020年6月17日 (水) 11:49時点における版
目次
ダウンロード
AssetStoreではなく以下からDLする。
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; } } }
設置方法
- 起動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")
日本語以外のとき翻訳
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