前回まで
前回は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の設定が必要です。
ただ、設定の仕方がちょっと問題ありまして…、
Smart機能を使いたい全てのセルに個別にSmartのチェックをしなければならないというわりと恐ろしいUIになっており、頻繁に動的文字列を使うプロジェクトでは、かなり大変な仕様となっています。言語ごとにチェックを入れる必要があるため、使用箇所と言語数に合わせて、設定する工数は2次元的に増えてしまいます。
※ショートカットまたは一括設定できるデフォルトの機能があれば、コメントで教えていただけると幸いです…。
一括設定機能を作る
セルの情報であるStringTableEntryさえ取得できれば、Smart機能のチェックは簡単です。
StringTableEntry entry;
entry.IsSmart = true;
まずは、StringTableCollectionを一括設定する汎用のメソッドを作ります。
パフォーマンスを考慮して、Smart機能を使うセルのみチェックを入れるべきでしょう。Smart機能の書式に使用される"{}"の文字列を含む場合のみSmartチェックを入れるような判定を行います。
#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チェックを入れる
複数シートで構成しているプロジェクトで、すべてのシートで一括設定をできるようにします。
//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から、スマートのチェックができるようになります。
GoogleSpreadSheet連携機能との合体
前回の記事ではGoogle Spread Sheetの全取得を実装しました。
こちらのStringTableCollectionのリストを編集して、スプレッドシートをプルした際に同時にSmart機能もチェックするように設定してみます。
//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が設定されるようになりました。
次の記事
未定
前の記事