しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Unity の Loalization でテキストの多言語対応する

※ これは 2022/10/06 時点の Unity 2022.1.19f1 Localization v1.0.5 の情報です

最新版では動作が異なる可能性がありますのでご注意ください

前回、UI のテキスト多言語対応をやってみたところ、フォントが英語と日本語両対応でないためうまく切り替えられなかったところを何とかしてみる

表示言語が切り替わったら文字列だけでなくフォントも一緒に切り替わるような対応を追加したい

フォントも含めて切り替え

とりあえず日本語フォントとして Google Fonts の NotoSansJP-Medium.otfAssets/Editor ディレクトリに配置

このフォントファイルを選択して右クリックメニューから [Create] - [TextMeshPro] - [Font Asset] を選択してアセット化しておく

日本語フォントをアセット化

次に AssetTable タイプの Localization Table を AssetTable として Assets/Localization ディレクトリに追加する

AssetTable

この AssetTableFont というキーで英語フォントと日本語フォントのアセットを登録する

Localization Table にフォントアセット登録

次に下記の LocalizedTmpFontEvent.csAssets/Scripts ディレクトリに追加する

using System;
using TMPro;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Events;
#endif
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Localization;
using UnityEngine.Localization.Components;

/// <summary>
/// TMP_FontAsset 用の LocalizeAssetEvent
/// </summary>
[AddComponentMenu("Localization/Asset/" + nameof(LocalizeTmpFontEvent))]
public class LocalizeTmpFontEvent : LocalizedAssetEvent<TMP_FontAsset, LocalizedTmpFont, UnityEventTmpFont>
{
#if UNITY_EDITOR
        [MenuItem("CONTEXT/TextMeshProUGUI/Localize Font")]
        private static void LocalizedTmpFontAsset(MenuCommand command)
        {
            var target = (TextMeshProUGUI)command.context;
            LocalizedTmpFontAsset(target);
        }

        public static LocalizeTmpFontEvent LocalizedTmpFontAsset(TextMeshProUGUI target)
        {
            var localizeEvent = (LocalizeTmpFontEvent)Undo.AddComponent(target.gameObject, typeof(LocalizeTmpFontEvent));
            
            // イベント発生時に font が変更されるように
            var setMethod = typeof(TextMeshProUGUI).GetProperty("font")?.GetSetMethod();
            if (setMethod != null)
            {
                var methodDelegate = (UnityAction<TMP_FontAsset>)Delegate.CreateDelegate(typeof(UnityAction<TMP_FontAsset>), target, setMethod);
                UnityEventTools.AddPersistentListener(localizeEvent.OnUpdateAsset, methodDelegate);
                localizeEvent.OnUpdateAsset.SetPersistentListenerState(0, UnityEventCallState.EditorAndRuntime);
            }
            
            return localizeEvent;
        }
#endif
}

/// <summary>
/// TMP_FontAsset を引数とする Unity Event
/// </summary>
[Serializable]
public class UnityEventTmpFont : UnityEvent<TMP_FontAsset> { }

Localization パッケージが用意している LocalizeStringEvent を真似て、表示言語が切り替わったらフォントを切り替えるエディター拡張を用意するという寸法

これを追加した状態で、文字列の場合と同様に TextMeshProUGUI のコンポーネント上で右上の三点リーダボタン押下でコンテキストメニューを表示、「Localize Font」を選択

Localize Font

すると LocalizeTmpFontEvent というコンポーネントが追加されるので、Localized Asset ReferenceAssetTable/Font を指定する

フォントの多言語対応設定

これで Localization Scene Controls ウィンドウで日本語に切り替えてみると・・・

フォントも含めて切り替え

ちゃんと日本語に切り替わった