アセット触ってみたシリーズ:ローカライズを楽に!「I2 Localization」

みなさん、ゲームの海外展開やっていますか?
昨年、Unityは中国のスマートフォンメーカーXiaomi社との提携を発表し、申し込みサイトのβ版が公開されています。中国にはGoogle Playがないため個人アプリの進出は難しかったのですが、これからは中国Android市場への展開がしやすく なりました。
もとより日本の個人開発ゲームでは、北米・欧州・アジア圏に展開しているものが徐々に増えているように感じます。
その際にハードルとなるのが「ローカライズ」用機能の開発です。国ごとに言語データや音声データを切り替える機能を作るのは骨が折れる作業です。
ローカライズシステムのポピュラーな手段としては、翻訳データをエクセルで管理し、それを何らかのバイナリに変換してゲームアプリ側に読みださせる仕組みを作ることです。
私が開発したゲームも、日・英のデータはScriptable Objectに変換してゲームに含める仕掛けにしていました。
しかし、こういった作業はゲームの面白さを煮詰めることとはあまり関係ないので、なんとか簡略化したいところですよね。
そこで!ローカライズ用のアセットを使おうというのが今回の趣旨となります。
ローカライズ機能を提供!「I2 Localization」
「I2 Localization」は、Unityに複数言語のローカライズ機能を提供するアセットです。
アセット提供元はInter-Illusionという会社さんで、I2、はInter-Illusionの略称のようです。
ウェブサイトにチュートリアルページがあります。
http://www.inter-illusion.com/tools/i2-localization/how-to-localize
「I2 Localization」はUnityの様々なUI環境に対応しています。
Unity標準のuGUIとレガシーなGUI、最近Unityが買収して無償化したTextMesh Pro、定番GUIシステムNGUIにも対応しています。
インポートしてフォルダを開くと、それぞれのサンプルシーンが確認できます。
今回はuGUIでの実装をベースに紹介します。サンプルはフォルダ位置I2\Localization\Examples\Targets\uGUI\uGUI Localization.sceneにあります。
このサンプルでは、uGUIパーツであるDropDown, Image, RawImage, Textの4要素がボタンで切り替わります。
Google Spreadsheetと連携!
セリフやアイテム名などの翻訳は専門の翻訳家にお願いすることが多いと思います。おそらく、そこではエクセルでデータをやり取りするでしょう。
csvファイルからの取り込みのほか、Google Driveと連携してリアルタイムにデータを更新することもできます。
GoogleのAPIを叩いてワンボタンで機械翻訳のデータを入力することもできます。
アセットで簡略化!
自作ツールのメンテナンスは面倒ですし、ローカライズにはいろいろと配慮しなくてはならない点が多いです。その最も有名な部分が「文字の長さの違いに対応する」ことでしょう。
実際に使ってみる
実際にゼロから「I2 Localization」を使ってみようと思います。テストプロジェクトとして、TextとButtonを適当に配置しただけのタイトル画面っぽいシーンを用意してみます。
翻訳データを用意する
「I2 Localization」は、翻訳データをフォルダResources/I2内の「I2Languages」プレハブに持ちます。
Resourcesという名称のフォルダはUnityの特殊フォルダ名で、この名称のフォルダ下に置かれたリソースはシーンに配置されていなくてもスクリプトから読み込むことができます。
まずはこの「I2Languages」プレハブを選択し、Languagesタブで今回使用する言語を指定します。とりあえず日、英、中にしてみましょう。
ドロップダウンメニューから言語を選択し、Addをクリックすることでリストに追加されます。
“Terms”は言葉ごとのルールを設定するタブです。
「I2 Localization」では呼び出し名となるキーと言語データのペアを「Term」と呼んでいます。このTermによって、ゲーム中の言語表示が差し変わる仕組みです。
Termは「Add Terms」ボタンか「+」ボタンから追加できます。今回はタイトル画面のスタートボタンで使うデータを用意するため、キー名は「Title_StartButton」とし、日本語訳は「スタート」英語は「Start」中国語(繁体字)は「開始」とします。
Unityエディタ上でコンポーネントを使ってTextにローカライズ設定を行う
Termを作成したら、次はそれを適用するコンポーネントを指定します。
シーン内のButtonゲームオブジェクトの下のTextを選択し、Add Componentから「Localize」コンポーネントを追加します。
このコンポーネントが同階層にあるTextコンポーネントの中身を書き換える役割を担います。
コンポーネントを追加したら、「Term」から先ほど作成したTitle_StartButtonを選んでおきましょう。
言語を切り替えるデバッグ機能を作る
Unityエディタ上で動作させるときはいつでも簡単に切り替えができることが望ましいため、今回は管理クラスを作成します。
名前は何でも構いませんが、とりあえず””LanguageSwitcher”としてみました。
I2 Localizationの関数はI2.Loc名前空間に記述されていますので、usingに追加します。
using I2.Loc;
using System.Collections.Generic;
using UnityEngine;
public class LanguageSwitcher : MonoBehaviour
{
private enum Language { JPN, ENG, CHI }
[SerializeField]
private Language currentLanguage;
private Dictionary<Language, string> languageStrDict = new Dictionary<Language, string>() {
{ Language.JPN, "Japanese" },
{ Language.ENG, "English" },
{ Language.CHI, "Chinese" },
};
private void Awake()
{
DontDestroyOnLoad(this.gameObject);
}
private void OnValidate()
{
ChangeLanguage(currentLanguage);
}
private void ChangeLanguage(Language language)
{
currentLanguage = language;
string languageStr = languageStrDict[language];
if (LocalizationManager.HasLanguage(languageStr))
{
LocalizationManager.CurrentLanguage = languageStr;
}
}
}
LocalizationManager.CurrentLanguageにstringで言語名を渡すとゲーム全体の言語設定が切り変わる仕組みですが、入力ミスが怖いのであらかじめenumで使用する言語のリストを作っておきます。
(LocalizationManager.CurrentLanguageCodeを使って”en-US”のようなIETF言語タグで指定することもできます。)
また、[SerializedField]アトリビュートを使ってインスペクタに現在の言語を表示できるようにし、OnValidateオーバーライド関数を利用してインスペクタ上で値が変更されたときにChangeLanguageメソッドが呼ばれるようにしています。
このスクリプトをシーンに追加しておくと、プレイしているときでもしていないときでも、いつでもI2 Localizationの言語切り替えを呼び出すことができます。
これで、簡単にローカライズ機能を導入することができました!
実際のゲームでは初起動時にOSの言語(Application.systemLanguage)を取得して言語の初期設定を決め、メニューなどで言語選択を用意するのがベターかと思います。
その場合は次のようなスクリプトを管理クラスに追加し、セーブデータがない状態で起動したときや設定をリセットされたときに呼び出すとよいでしょう。
private void ChangeBySystemLanguage()
{
switch (Application.systemLanguage)
{
case SystemLanguage.Chinese:
ChangeLanguage(Language.CHI);
break;
case SystemLanguage.English:
ChangeLanguage(Language.ENG);
break;
case SystemLanguage.Japanese:
ChangeLanguage(Language.JPN);
break;
default:
ChangeLanguage(Language.ENG);
break;
}
}
スクリプトから言語データを読みこむ
Localizeコンポーネントではなく、スクリプトで言語データにアクセスしたい場合はI2.Loc名前空間のScriptLocalization.Get()で取得することができます。
public Text titleButtonText;
private void Start()
{
titleButtonText.text = ScriptLocalization.Get("Title_StartButton");
}
UIに動的な処理をする場合や、独自のタイミングでデータを流し込みたいときに有効です。
本アセットの特筆するべき点
このアセットを触っていて気が付いたのですが、I2 Locaizationは あとから設定を変更すること が容易にできるようになっています。
これまで解説した機能でいうならば、Termのキー名を後から変更しても、シーン内での設定はその変更に追従してくれます。
こういった機能を自作した場合、たとえばenumで呼び出し名を管理していたりすると、そのenumの変更によって設定が壊れることが良くあります。
I2 Locaizationならば、「管理ルールを変えてキー名を変更したいな」と思ったときも、いちいちTextコンポーネントへ名前を変えたキーを再設定しなくて済みます。
その他の便利機能
「I2 Localization」には、紹介した基本機能のほかにも沢山の便利機能が含まれています。
- アラビア語など、右から左へ流れる言語向けの対応
- 言語ごとのフォントデータ・フォントサイズの変更
- サーバーからCSVファイルで言語データを読み込み可能
- タッチデバイスの場合の言語設定を別途持つことが可能
- iOS/Androidのストア登録時の言語指定ファイルを自動生成
ちょっとしたTips
NGUIなどの他のアセットと連携させる場合、読み込み順序によってはI2 Localizationがうまく認識しない場合があります。そのときはTools/I2 Localization/Enable Plugins/Force Detectingを実行すると再読み込みが走ります。
まとめ
ローカライズ開発でありがちな手順や使い方がはじめから想定されたこのアセットを使うことで、関連する作業の時間を短縮することができそうです。
なにより、ツール化・ドキュメント化されていることで複数人での作業にも適しています。アプリの海外展開を検討している皆様は、ぜひI2 Localizationを導入してみてください。
この記事を書いた人
一條貴彰株式会社ヘッドハイ 代表取締役
ゲーム作家・Game DevRel。小規模ゲーム開発者がもっと活躍できる世の中作りを目指して、ゲーム開発ツール・サービス専門のDeveloper Relation事業を行っています。ゲーム作家としての代表作は『Back in 1995』(Steam)。