0
0

Unity Localizationを実用化してみよう。③Smartのチェックを一括化する【hako 生活の休日】

Last updated at Posted at 2024-09-08

前回まで

前回はGoogleSpreadSheetからいつでもすべてのシートの情報を同期できるようにしました。

動的文字列を便利に扱える、"SmartString"機能

Unity Localizationには、 Smart Stringという強力な動的文字列の処理機能があります。

変数を文字列中に入れたい時など、動的な書式を表示するための便利な機能です。
例えば、

こんにちは。{login}回目のログインです。

という文字列を用意して、以下のコードで出力します。

LocalizedString lstr = new LocalizeString("テーブルの名前","エントリーのID");
var value = new IntVariable();
value.Value = v;
lstr.Add(key, value);
lstr.RefreshString();
//こんにちは。10回目のログインです。

切り替え機能

セレクター・フォーマッターといった機能が用意されています。

複数形の表記なども簡単に扱うことができます。

Smart機能のチェック大変すぎ問題

さて、大変便利なSmart機能ですが、StringTableCollectionの設定が必要です。
ただ、設定の仕方がちょっと問題ありまして…、

image.png

Smart機能を使いたい全てのセルに個別にSmartのチェックをしなければならないというわりと恐ろしいUIになっており、頻繁に動的文字列を使うプロジェクトでは、かなり大変な仕様となっています。言語ごとにチェックを入れる必要があるため、使用箇所と言語数に合わせて、設定する工数は2次元的に増えてしまいます。

※ショートカットまたは一括設定できるデフォルトの機能があれば、コメントで教えていただけると幸いです…。

一括設定機能を作る

セルの情報であるStringTableEntryさえ取得できれば、Smart機能のチェックは簡単です。

StringTableEntry entry;
entry.IsSmart = true;

まずは、StringTableCollectionを一括設定する汎用のメソッドを作ります。
パフォーマンスを考慮して、Smart機能を使うセルのみチェックを入れるべきでしょう。Smart機能の書式に使用される"{}"の文字列を含む場合のみSmartチェックを入れるような判定を行います。

C# LocalizeUtil.cs
#if UNITY_EDITOR
using UnityEditor.Localization;
using UnityEngine.Localization;
using UnityEngine.Localization.Tables;

/// <summary>
/// Localizeに関する汎用機能
/// </summary>
public static class LocalizeUtil
{
    //forceにチェックをいれた場合は文法チェックをスルーして、直接Smart化します

    public static void SetSmart(StringTableCollection collection, bool all)
    {
        var tables = collection.Tables;
        foreach (var table in tables)
        {
            var stable = table.asset as StringTable;
            foreach (var t in stable)
            {
                var str = t.Value.ToString();
                t.Value.IsSmart = all || (str.Contains('{') && str.Contains('}'));
            }
        }
    }
}
#endif

すべてのStringTableCollectionにSmartチェックを入れる

複数シートで構成しているプロジェクトで、すべてのシートで一括設定をできるようにします。

C# StringTableCollectionList.cs
//StringTableCollectionを一括管理するScriptableObject
//このスクリプトは任意のEditorフォルダ以下に配置すること。
#if ODIN_INSPECTOR
// Odin Inspectorを使う前提ですが、なくても動きます。
using Sirenix.OdinInspector;
#endif
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Localization;
using UnityEngine;

[CreateAssetMenu(menuName = "Localization拡張/StringCollectionList")]
public class StringTableCollectionList : ScriptableObject
{
	public List<StringTableCollection> collections = new List<StringTableCollection>();

#if ODIN_INSPECTOR
	[Button]
#endif
    [ContextMenu("CheckSmartAll")]
	public void CheckSmartAll()
    {
		foreach (var collection in collections)
		{
			LocalizeUtil.SetSmart(collection, false);
		}
	}
}

作成したScriptableObjectのコンテキストメニューのCheckSmartAllから、スマートのチェックができるようになります。

image.png

GoogleSpreadSheet連携機能との合体

前回の記事ではGoogle Spread Sheetの全取得を実装しました。

こちらのStringTableCollectionのリストを編集して、スプレッドシートをプルした際に同時にSmart機能もチェックするように設定してみます。

C# StringTableCollectionList.cs
//StringTableCollectionを一括管理するScriptableObject
//このスクリプトは任意のEditorフォルダ以下に配置すること。
#if ODIN_INSPECTOR
// Odin Inspectorを使う前提ですが、なくても動きます。
using Sirenix.OdinInspector;
#endif
using System.Collections.Generic;
using System.Linq;
using UnityEditor.Localization;
using UnityEditor.Localization.Plugins.Google;
using UnityEngine;

[CreateAssetMenu(menuName = "Localization拡張/StringCollectionList")]
public class StringTableCollectionList : ScriptableObject
{

	public string SpreadSheetID = "任意のSpreadSheetID";
	public SheetsServiceProvider ssp;
	public List<StringTableCollection> collections = new List<StringTableCollection>();

#if ODIN_INSPECTOR
	[Button]
#endif
    [ContextMenu("PullAll")]
//シートをPullするやつ
	public void PullAll()
    {
		var gss = new GoogleSheets(ssp);
		gss.SpreadSheetId = SpreadSheetID;
        //ループでそれぞれ取得(取得の是非の判定は割愛)
		foreach (var collection in collections)
		{
			var sheetsExtension = collection.Extensions.OfType<GoogleSheetsExtension>().FirstOrDefault();
			gss.PullIntoStringTableCollection(
				sheetsExtension.SheetId,
				collection,
				sheetsExtension.Columns,
				createUndo: true);

			//ここで同時にSmartの設定を行う
			LocalizeUtil.SetSmart(collection, false);
		}
	}
#if ODIN_INSPECTOR
	[Button]
#endif
    [ContextMenu("OpenSheet")]
//シートを開くやつ
	public void OpenSheet()
	{
		GoogleSheets.OpenSheetInBrowser(SpreadSheetID);
	}
}


#if ODIN_INSPECTOR
	[Button]
#endif
    [ContextMenu("CheckSmartAll")]
	public void CheckSmartAll()
    {
		foreach (var collection in collections)
		{
			LocalizeUtil.SetSmart(collection, false);
		}
	}
}

これで、SpreadSheetからPull Allした際に自動でSmartが設定されるようになりました。

次の記事

未定

前の記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0