UnityのLocalizationPackageを触ってみた

Applibot Advent Calendar 2020」 24日目の記事になります。
前日は@TakumaKurosawaさんのECSでService Discoveryを使ってみようという記事でした!

今回の記事では、UnityのLocalizationPackageを触ってみて、その使い方について書いていきたいと思います。


目次

  1. はじめに
  2. 導入方法
  3. 初期設定
  4. テキストのローカライズ
  5. おわりに

1. はじめに

UnityのLocalizationPackageとは、UnityのPackageManagerにより提供される、テキストや音声ファイル、画像ファイルなどのローカライズ対応をサポートするためのパッケージです。

Unity2019.3以降に対応し、2020年12月現在はpreview版であるLocalization 0.9.0-previewが最新版として提供されています。

まだpreview版であるため、実際の開発に利用するにはリスクが伴いますが、最近のアプリはグローバル展開されることが多く、今後よく使われるパッケージとなることが予想されるため、今回は検証も兼ねて触っていきたいと思います。

なお、preview版のパッケージは頻繁に使い方やUIの大幅な変更があるため、それを踏まえてご参考にしていただければと思います。

検証環境は次のようになります。

Unity 2020.1.16f1
Localization 0.9.0-preview

2. 導入方法

まず、プロジェクトへのLocalizationPackageの導入方法について説明します。

LocalizationPackageは、UnityのPackageManagerにより提供されているため、PackageManagerから簡単に導入が可能です。

Window > Package Managerを選択すると、次のようなウィンドウが開かれます。

画像のUnityRegistryを選択することで、Unityが提供しているパッケージ一覧が表示されますが、今回のLocalizationパッケージはpreview版であるため、デフォルトの表示では表示されません。

そのため、Localization Packageを導入するには、PackageのgitURLを用いる必要があります。

次の画像で表示されている、Add package from git URL を選択し、com.unity.localization と入力することでインポートが開始されます。

Previewのパッケージを頻繁に試したい方は、PackageManagerの設定画面からPreviewのパッケージをUnityRegistryに表示する設定にすることもできるため、そちらの方法で導入を行っても良いと思います。


3. 初期設定

次に、導入したLocalizationPackageの初期設定を行います。

まずはあらゆるローカライズの設定を保持するための、LocalizationSettingsを作成します。

メニューバーのEdit > Project Settings > Localizationを開き、Createボタンを押すことで作成できます。

作成が完了したら、プロジェクトで扱いたいLocaleを設定します。

Localeとは、地域のことで、アプリケーションをどの言語にローカライズしたいかを設定することになります。

Localeを設定するには、さきほど開いたProjectSettingsのLocalizationタブを押してください。

すると、次の画像のようにLocale一覧を選択できる画面が開かれます。

基本的にはLocaleはこちらの画面から選択して、GenerateLocalesボタンを押すことで作成できます。

これらのLocaleは、.NetのCultureInfoクラスのラッパーとなっていて、デフォルトではCultureInfoに存在しないロケールは設定できませんが、カスタマイズをすることも可能です。

最後に、選択したLocale一覧から、アプリケーション初回起動時に使用するLocaleを選択する方法を設定します。

Localeの選択は、Locale Selectorによって行われます。

Locale Selectorは、次の画像のLocale Selectorsに設定されているSelectorを利用して、使用する言語を決定します。

Selectorは上から順に呼ばれ、選択されているLocaleとマッチするLocaleを返すことができるSelectorがあったら、その時点でLocaleを決定します。

例えば、上の画像を参考に説明すると、

  1. Command Line Locale Selectorによって、コマンドライン上でLocaleが設定されていればそのLocaleを選択、されていなければ2へ
  2. System Locale Selectorによって、Application.systemLanguageが返すLanguageとマッチするLocaleがあれば選択、なければ3へ
  3. Specific Locale Selectorによって、デフォルトで設定されているLocaleを選択

となります。

Locale SelectorによるLocaleの選択は、どのLocaleを使用するかが選択されていない場合に利用されます。

実際のアプリでは、メニュー等から使用したい言語をユーザーに任意で設定させたい場合もあると思いますが、その場合はこちらのドキュメントのように、LocalizationSettings.SelectedLocaleを設定してください。


4. テキストのローカライズ

次にテキストのローカライズについて説明します。

UnityのLocalizationPackageでは、テキストに限らずローカライズするものは、KeyValueのテーブルで管理されます。

各テーブルは、Window > AssetManagement > Localization Tablesを選択し、New Table Collectionタブにて作成できます。

上の画像のように、Localeを選択し、テーブル名を入れた状態でCreate String Table Collectionを選択することでテキストのローカライズ用テーブルが作成できます。

作成したテーブルは、隣のタブのEdit Table Collectionを選択することでエディタ上で編集できます。これらのテーブルはCSVファイル等にExportやImportができるため、大規模な開発ではそちらの形式を使って管理するのが良いかもしれません。

Localization Packageの特徴として、特定の変数の値を埋め込むPlaceHolderをサポートしているのはもちろんのこと、SmartStringに対応していることが挙げられます。

SmartStringとは、string.Formatを拡張して、条件分岐や複数形、リスト表示などをサポートするライブラリです。

日本語を英語版にローカライズ対応する際に少し大変な、単数、複数形の対応などが簡単にできます。

var players = new List<string>() {"player1", "player2", "player3"};
Smart.Format("Current: {0} {0:player|players}", players.Count);
// 出力: "Current: 3 players"
// もしリストの要素が1なら、 "Current: 1 player"

今回は、エディタ上でいくつかKeyValueを追加し、実際にローカライズされたテキストを表示してみました。

テーブルには、次の画像のようなKeyValueを登録しました。

Smartというチェックボックスにチェックを入れることで、SmartStringの対応をすることができます。

また、次のようなTextMeshProUGUIに対応したローカライズ用コンポーネントを作成しました。

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Localization;

namespace Localize
{
    /// <summary>
    /// TextMeshProUGUIをローカライズするためのコンポーネント
    /// </summary>
    public class LocalizeTextMeshProEvent : MonoBehaviour
    {
        [Serializable]
        public class StringUnityEvent : UnityEvent<string> {};
        [SerializeField]
        private LocalizedString _localizedString = new LocalizedString();
        [SerializeField]
        private StringUnityEvent _updateString = new StringUnityEvent();
        [SerializeField]
        private int _argument = 0;

        /// <summary>
        /// Localizeされたテキストが更新されたときに呼ばれるコールバック
        /// </summary>
        public StringUnityEvent OnUpdateString
        {
            get => _updateString;
            set => _updateString = value;
        }
        
        /// <summary>
        /// LocalizedStringに変更があったら、Textを更新する
        /// </summary>
        /// <param name="value">更新されたテキスト内容</param>
        private void UpdateString(string value)
        {
            OnUpdateString.Invoke(value);
        }

        /// <summary>
        /// LocalizedStringに変更があった際に呼ぶイベントを登録する
        /// </summary>
        private void RegisterChangeHandler()
        {
            _localizedString.Arguments = new object[] {_argument};
            _localizedString.StringChanged += UpdateString;
        }

        /// <summary>
        /// LocalizedStringに変更があった際に呼ぶイベントを解除する
        /// </summary>
        private void ClearChangeHandler()
        {
            _localizedString.StringChanged -= UpdateString;
        }

        #region UNITY_EVENT

        private void OnEnable()
        {
            RegisterChangeHandler();
        }

        private void OnDisable()
        {
            ClearChangeHandler();
        }

        #endregion
    }
}

今回は、こちらのコンポーネントを使って、エディタ上でキーを選択したり、引数を設定できるようにしました。

LocalizedString という存在するStringAssetTableからInspector上でキーを設定できる型を活用することで、次のようなインスペクタの表示になります。

このように設定することで、最終的には選んだKeyと対となるValueが、現在のLocaleの設定に合わせて表示されます。

また、PlaceHolderとSmartStringを活用することで、文字列に任意の値を動的に埋め込むこともできます。


5. おわりに

今回は、UnityのLocalizationPackageの導入と初期設定から実際にテキストをローカライズするところまでをまとめました。

このパッケージでは、テキストの他に画像や音声ファイルもローカライズ可能です。また、拡張性がとても高いため、それ以外のファイルをローカライズの対象とすることもできます。

本記事を読んで、もし興味を持った方はぜひ触ってみてください。

以上、 「 Applibot Advent Calendar 2020 」 24日目の記事でした。
明日は @borasyo さんです。


関連記事一覧

  1. この記事へのコメントはありません。