検索しても実装してるスクリプト見当たらないなって思ったけど
もう少し検索していると、
Unityのチュートリアルの中に
「ライブセッション:ローカライゼーションツール」というのがあったので
ここのスクリプトを使ってみる(動画はみてません)
Localized Text Component - Unity
- LocalizationData.cs
- LocalizationManager.cs
- StartupManager.cs
- LocalizedText.cs
- LocalizedTextEditor.cs
処理を調整
(localizedText_en.json, localizedText_de.json) があったのでとりあえず、localizedText_ja.json も追加する。
{"items":[{"key":"test1","value":"テスト"},{"key":"test2","value":"てすと。"}]}
StartupManager.cs の内容を、自分のプロジェクトの初期化のシーンで呼ぶようにする。
IEnumerator Start()
{
LocalizationManager.instance.LoadLocalizedText("localizedText_ja.json");
yield return new WaitUntil(LocalizationManager.instance.GetIsReady);
// 遷移とか
}
LocalizedText.cs に、RequireComponentをつけておく。
+ [RequireComponent(typeof(Text))]
public class LocalizedText : MonoBehaviour
TextMeshProUGUI だとこう。
+ [RequireComponent(typeof(TextMeshProUGUI))]
public class LocalizedText : MonoBehaviour
多分そんな感じで使っていけば、良さそうです。
おわり。
以降は、なんかやりたいことをやっている・・なにかです(?)
(playしてない時)エディタ上でUIレアウト確認用に、日本語を入れておきたい。
OnValidate() で、キーが変更されるたびに、テキストの値も置き換えるようにする。
キーが間違ってると、"Localized text not found"
になるからわかりやすくてお気に入り。(っていうか、enum使えって話かな。)
本当は、テキストの部分(TextMeshProUGUI.text)はインスペクタ上でさわれないようにしたい
[CustomEditor(typeof(TextMeshProUGUI))] すればいいのかな・・。
(clickで開く LocalizedText.cs)
using TMPro;
using UnityEngine;
namespace Localization
{
/// <summary>
/// キー設定用
/// </summary>
[RequireComponent(typeof(TextMeshProUGUI))]
public class LocalizedText : MonoBehaviour
{
[SerializeField] string key;
public string GetKey => key;
private TextMeshProUGUI _ui;
private TextMeshProUGUI UI => _ui ?? GetComponent<TextMeshProUGUI>();
private string value;
#if UNITY_EDITOR
public void OnValidate()
{
if (UI != null) UI.text = LocalizationManager.GetLocalizedValue(key);
}
#endif
public void Awake()
{
if (string.IsNullOrEmpty(value))
{
var txt = LocalizationManager.GetInitializeValue(key);
UI.text = txt;
}
else UI.text = value;
}
/// <summary>
/// キー変更
/// </summary>
public void TextWithKey(string key, params object[] args)
{
this.key = key;
Text(args);
}
/// <summary>
/// テキストを設定する
/// </summary>
public void Text(params object[] args)
{
string format = LocalizationManager.GetLocalizedFormat(key);
value = string.Format(format, args);
UI.text = value;
}
}
}
(string format)と(bool 初期値として使うかどうか)を追加する
+ /// <summary>
+ /// The key.
+ /// </summary>
public string key;
+ /// <summary>
+ /// The format.
+ /// </summary>
+ public string format;
+ /// <summary>
+ /// The value.
+ /// </summary>
public string value;
+ /// <summary>
+ /// true:実行時にはvalue入れないで空にする。UIレアウト確認用。false:実行時もそのまま使う
+ /// </summary>
+ public bool value_is_test;
public static class LocalizationManager
{
- private static Dictionary<string, string> localizedText;
+ private static Dictionary<string, LocalizationItem> localizedText;
private static readonly string missingTextString = "Localized text not found";
+ private static readonly string missingFormatString = "{0}";
全体としてはこう。
StreamingAsset やめて Resources.Load にして楽してる。
のちのち、ロードは変更すると思う。
(clickで開く LocalizationManager.cs)
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Localization
{
/// <summary>
/// Localization manager.
/// </summary>
public static class LocalizationManager
{
private static Dictionary<string, LocalizationItem> localizedText;
private static readonly string missingTextString = "Localized text not found";
private static readonly string missingFormatString = "{0}";
/// <summary>
/// 準備状態を取得する
/// </summary>
public static bool IsReady { get; private set; } = false;
/// <summary>
/// 読み込み開始
/// </summary>
public static void LoadLocalizedText()
{
if (IsReady) return;
LoadAsset();
}
/// <summary>
/// 読み込み
/// </summary>
public static void LoadAsset()
{
string filePath = Path.Combine("Localization", "common_ja");
string dataAsJson = Resources.Load<TextAsset>(filePath).text;
CreateDictionary(dataAsJson);
}
/// <summary>
/// 設定する
/// </summary>
private static void CreateDictionary(string dataAsJson)
{
localizedText = new Dictionary<string, LocalizationItem>();
LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);
for (int i = 0; i < loadedData.items.Length; i++)
{
localizedText.Add(loadedData.items[i].key, loadedData.items[i]);
}
Debug.Log("Data loaded, dictionary contains: " + localizedText.Count + " entries");
IsReady = true;
}
/// <summary>
/// ローカライズされた値を取得する
/// </summary>
public static string GetLocalizedValue(string key)
{
#if UNITY_EDITOR
if (string.IsNullOrEmpty(key)) return missingTextString;
if (!UnityEditor.EditorApplication.isPlaying
&& localizedText == null) LoadAsset();
#endif
if (!localizedText.ContainsKey(key)) return missingTextString;
localizedText.TryGetValue(key, out LocalizationItem result);
return result.value;
}
/// <summary>
/// ゲーム中の初期値を取得する
/// </summary>
public static string GetInitializeValue(string key)
{
if (!localizedText.ContainsKey(key)) return missingTextString;
localizedText.TryGetValue(key, out LocalizationItem result);
if (result.value_is_test) return null;
return result.value;
}
/// <summary>
/// ローカライズされたテキストフォーマットを取得する
/// </summary>
public static string GetLocalizedFormat(string key)
{
localizedText.TryGetValue(key, out LocalizationItem result);
if (string.IsNullOrEmpty(result?.format)) return missingFormatString;
return result.format;
}
}
}
1ファイルはしんどいから、ファイル分割したい。
あとは、
とっても大きなファイルになりそうなので
ファイル分けが出来ると、幸せになれると思う。
private static void LoadAsset()
{
- string filePath = Path.Combine("Localization", "common_ja");
- string dataAsJson = Resources.Load<TextAsset>(filePath).text;
- CreateDictionary(dataAsJson);
+ var txt = Resources.LoadAll<TextAsset>("Localization/ja");
+ CreateDictionary(txt);
}
/// <summary>
/// 設定する
/// </summary>
- private static void CreateDictionary(string dataAsJson)
+ private static void CreateDictionary(TextAsset[] txt)
{
localizedText = new Dictionary<string, LocalizationItem>();
+ var objs = txt.Select(o => JsonUtility.FromJson<LocalizationData>(o.text));
- LocalizationData loadedData = JsonUtility.FromJson<LocalizationData>(dataAsJson);
- for (int i = 0; i < loadedData.items.Length; i++)
- {
- localizedText.Add(loadedData.items[i].key, loadedData.items[i]);
- }
+ foreach (var o in objs)
+ foreach (var item in o.items)
+ localizedText.Add($"{o.prefix}-{item.key}", item);
public class LocalizationData
{
+ /// <summary>
+ /// The prefix.
+ /// </summary>
+ public string prefix;
/// <summary>
/// The items.
/// </summary>
public LocalizationItem[] items;
いい感じ。