Unityエディタ拡張で多言語対応する方法

Unityのスクリプトリファレンスを調べていたらLocalizationAssetなるクラスが2018.3から追加されているのに気づきました。

https://docs.unity3d.com/ja/current/ScriptReference/LocalizationAsset.html

お、これは便利そう。
Arborでは翻訳テキストから拾ってくる機能を自作していたので、Unity標準で多言語対応できるなら嬉しいなー。
なんて思いながら、どう使うか調べてみました。

Unityのマニュアルなどにも詳細が載っていなく手探りで動作確認しているため間違っている可能性もあります。
正式にサポートされているかも不明であるため、今後の更新で使えなくなる可能性もあります。
ご注意ください。

なお動作確認には、Unity 2019.4.0を使用しています。

LocalizationAsset

まずLocalizationAssetをUnity上で作成する方法についてですが、poファイルを作成するとUnity上ではLocalizationAssetとして認識されるようです。

poファイルとは

poファイルとは、gettextと言われるライブラリで使用される翻訳文を記入するテキストファイル規格で、様々なプロジェクトで使用されています。

Unity自体の多言語対応もこのpoファイルを使用しており、日本語パックをインストールすると、Unityのインストールフォルダ/Editor/Data/Localization/ja.poが追加されます。

このpoファイルをUnityのプロジェクトに配置すると、LocalizationAssetとして認識されるようになります。

poファイルの作成

poファイルの作成は、PoEditなどのソフトを使用して作成します。

詳しくはpoファイルの作成方法などググってください。

Unityで使用するにあたっての注意点としては、poファイルの設定の言語にjaなどを設定しておく必要があります。

今回は試しに以下のファイルを作成してみました。

msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ja\n"

msgid "caitsithware"
msgstr "ケットシーウェア"

ja.poという名前でテキストファイルを作成、UTF-8で保存してください。

エディタ拡張で使う

Unityに日本語パッケージを追加する

UnityのインストーラーもしくはUnity Hubのモジュール追加で日本語パッケージをインストールします。

Unityエディタを日本語にする

Preferencesを開き、Languageを日本語にします。

Assembly Definition Fileを作成する

まずはエディタ拡張のアセンブリをasmdefで分離させます。

PlatformsはEditorだけにしておいてください。

poファイルを配置

作成したasmdefのフォルダ以下にpoファイルを置きます。

試しにLocalizationフォルダを作成して置いてみましたが問題なく使用できるようなので、フォルダ構成は関係ないかLocalizationは特別にOKとなっているかもしれません。

アセンブリにLocalization属性を追加

作成したasmdefと同じフォルダにAssemblyInfo.csといった名前(何でも良さそうですが)のファイルを作成。

using UnityEditor.Localization.Editor;

[assembly: Localization]

と記入。

Localization.Tr()で翻訳文を取得

翻訳文を取得するには、Localization.Tr()メソッドを使用します。

// ファイル冒頭
using UnityEditor.Localization.Editor;

// メソッド内
string text = Localization.Tr("caitsithware");
Debug.Log(text); // UnityEditorを日本語にしていると「ケットシーウェア」と出力される。

なお、Unity2020.1ではLocalization.Tr()はObsoleteになっており、UnityEditor.L10n.Tr()を使うように警告が出ます。
ただし2019.4でL10n.Tr()だけを使用すると翻訳テキストの取得が失敗してしまうので注意してください。

補足:別Assemblyの翻訳データ

翻訳データはAssemblyごとに割り当てられているため、別アセンブリの翻訳データを参照したい場合はLocalizationGroupの指定が必要なようです。

Trで指定

Trメソッドの第二引数に、アセンブリ名(asmdefで設定した名前)を指定すると、翻訳データの参照が切り替わります。

// ファイル冒頭
using UnityEditor.Localization.Editor;

// メソッド内
Localization.Tr("caitsithware","ArborEditor"); // ArborEditorアセンブリにあるja.poからとってくるようになる。

LocalizationGroupで指定

指定した範囲内の翻訳データの参照先を変更するにはLocalizationGroupを使用します。

// ファイル冒頭
using UnityEditor.Localization.Editor;

// メソッド内
using (new LocalizationGroup(typeof(使おうとしている型)))
{
	Debug.Log(Localization.Tr("caitsithware")); // 使おうとしている型が入っているアセンブリのja.poからとってくるようになる。
}

LocalizationGroupで指定した型が格納されているアセンブリにある翻訳データを使用するようになります。
なお、このLocalizationGroupの中であれば、Unity 2019.4でもL10n.Tr()が使えました。
LocalizationGroupで囲んで使うのが正しい使用方法なのかもしれませんね。

LocalizationAttributeで参照先翻訳データの共有

LocalizationAttributeでも参照先アセンブリ名を指定できるので、別アセンブリの翻訳データをアセンブリ内全体で共有する使い方もできます。

[assembly: Localization("ArborEditor")] // ArborEditorアセンブリにあるja.poからとってくるようになる。

まとめ

この機能があれば、自作のエディタ拡張アセットでも簡単に多言語対応できそうです。
アセット開発者(特に私みたいに独自に多言語対応してた人)にとっては嬉しい機能ですね。

Unityさん、なんでまともなマニュアルないんですか……

追記:

Uniryフォーラムに使い方の解説が上がってました : https://forum.unity.com/threads/package-ui-localization-is-available-in-2020-2.957173/

Unityのアセット販売中!

ステートマシンの状態遷移やパラメータはエディタで編集でき、
ゲームロジックに依存するステートの挙動はスクリプトで記述可能なエディタ拡張。

詳細はこちら

RPGツクールVXやWOLF RPGエディターのオートタイルに準拠したエディタ拡張。

詳細はこちら

オススメ!