※ 本記事にはプロモーションが含まれています。
こんにちは! ねこです。
今、遊びでやっているゲーム制作。
その中で行っていこうと考えているものの一つに他言語対応があります。
私が、そのためにやりたいことは以下の内容になります。
- プロジェクトのバージョンは一つに固定したい(言語ごとに違うバージョンを作らない・アセットバンドルは除く)。
- 他言語テキストは、外部ファイルで管理したい。
- 装飾文字に画像を使用しない(でも、クオリティは落とさない)。
しかし、一口に他言語対応とはいえ、以下の箇所を個別にどのように対応するかを考えないといけません。
- UI などに静的に配置しているテキスト
- プログラムなどで動的に挿入するテキスト
- マスターデータから受け取って表示するテキスト
- ノベル(物語)のスクリプトを表示するテキスト
うーん、個人規模でやるには、なかなか大きい 笑。
でも、チャレンジすることに意味がありますね、ひとつづつ見ていきましょう。
他言語対応でやりたいこと
まずは、要件定義を行うために、要望とリスクを洗い出しましょう。
1. プロジェクトのバージョンは一つに固定したい
実際のゲームプロジェクトのローカライズは、言語ごとにプロジェクトブランチやリポジトリを切ったりして、開発するケースがほとんどだと思います。
しかし、マンパワーを必要とする更新作業ができないということもあります。
ですので、最初から他言語対応前提に考えた上で、どのローカライズも同じプロジェクト(mater)を参照させたいです。
また、ゲームの更新についても、なるべくアプリのアップデートをせずに行えるようにしていきます。
2. 他言語テキストは、外部ファイルで管理したい
上記の内容は、おそらく開発者全員が夢想する大理想ではあります。
しかし、実際に開発・運用を行う上で、以下の問題が出てくることが考えられます。
- 各ローカライズの運用を(たとえ1箇所だけでも)個別に運用したい場合にどうするか?
- 要素の一部に独自の問題(特定の国のみの表現規制など)が発生した場合どうするか?
つまり、各ローカライズの独自対応に融通を効かせるためには、本体プログラムに依存しない構成にしないと難しいですが、これがなかなか厄介。
これらの問題を解決するために、ゲームの構成要素のうち、以下の内容を外部管理する必要があります。
- ゲームの定数(各要素のバージョンなど)
- フラグデータ
- マスターデータ
- UI 以外の画像・アニメーションデータ(キャラクターなど)
- 音楽データ
- 一部を除くテキストデータ・フォントデータ
それをふまえて、設計を考えましょう。
3. 装飾文字に画像を使用しない(でも、クオリティは落とさない)
よく実際のプロジェクトでは、演出などに使うような装飾文字は、画像として配置するケースが多いです。
しかし、言語が増えるたびにそれらを書き出すことは手間なので今回はしません(てか、できません)。
じゃあ装飾系の文字はどうするか?
それは、 Unity 標準の幅広い表現・装飾、細かな設定が可能な TextMesh Pro を使っていきます。
また、TextMesh Pro も、以下の機能が追加されたことで、さらに汎用性が高くなりました。
- Font Fallback … 複数のフォント素材を合成して 1 つのフォントとして扱う
- Dynamic SDF System … 動的に元のフォントデータから文字テクスチャを生成して使用可能
そのため、極論ですが、日本語・中国語のような文字数の多い言語の全てのテキストを TextMesh Pro で描画することも(理論上)可能です。
しかし、正直、全てを TextMesh Pro で行うのは狂気の沙汰です 笑。
これは、結論からいうと、日本語・中国語のような文字数が多い言語の対応を踏まえて考えると、
- 演出(デザイン文字) … TextMesh Pro
- 本文など … Text (uGUI)
のような使い分けを考えるほうが現実的です。
・・・しかし、全てのフォントを TextMesh Pro に・・・、していきましょう!
他言語対応の具体的な実装方法
それでは、具体的な実装方法を決めていきます。
全体の概要
まず、アプリのプロジェクトデータ。これは、前提でお話した通り全てのローカライズで同一のものを利用します。
そして、外部からダウンロードして利用するもの、これは全てのローカライズで個別に作ります。
それらを管理するバックエンドは、Google の Firebase というアプリケーション開発プラットフォームを利用します。
そこで各ローカライズごとに Firebase アプリを制作して管理すればいいでしょう。
これを図に表すと、こんな感じになります。
個別のテキストの管理方法
外部データは、基本的には Unity 内で管理し、アセットバンドルにして Addressable でやりとりします。
ただ、テキストで管理可能なものについては、G Suite(Googole ドライブ・スプレッドシート)で制作し、書き出したデータは、Unity とは別リポジトリ管理し、デプロイ時に暗号化してアップロードする仕組みを作ります。
以下、これらが各言語ごとに個別のスプレッドシートとに持つ想定になります。
- ゲームの定数 … スプレッドシート(json 書き出し)
- マスターデータ … スプレッドシート(json 書き出し)
- フラグデータ … スプレッドシート(json 書き出し)
- UI テキスト … スプレッドシート(json 書き出し)
- ノベルのスクリプトデータ … Naninovel テキストデータ(.nani ファイル)
制作時に不便すぎたら、Unity 内で管理するかもですが。。
運用の流れとしては、まず日本語で制作し、他の言語に反映させるタイミングで複製・マージ、翻訳を行なう感じになれば理想です。
UI テキストについて
ここで、UI に表示するテキストについて補足します。
これら UI の表示テキストは、Key, Value で下記のような管理をします。
取得方法は、マスターデータと同じ方法で行います(Json データを、Entity のリストで取得)。
次に表示方法です。
UI テキストの中でも、テキストコンポーネントに直接書いてて問題ない静的なテキストと、条件によって表示内容が変わる動的なテキストがあります。
動的なテキストは、API からテキストデータを取得して、該当 Key から、Value を取得してセットします。
静的なテキストは、テキストオブジェクトに他言語設定用のコンポーネントを追加して Key を設定すると、再生時に自動的に該当 Value が表示されるように対応します。
これらの具体的な実装方法については、後日紹介します。
あと、TextMesh Pro の他言語対応についても。
キャラ・アイテムなどの画像の管理方法
開発現在は、上記のテキスト含む、画像データも一旦 Addressable で管理しています。
しかし、画像データについても、可能ならアセットバンドルにせずに生のデータを利用したいと考えています。
理由は、各ローカライズごとに異なる画像をストレージ上で簡単に差し替えできるようにしたいため。
あとは、Addressable で管理すると、少なくとも Unity 側が該当ファイルのアドレスを先に知っていないといけないので、それはそれで不便かなと。
うまくいけば、アセットバンドルを各言語ごとに書き出ししなくても良くなるかも、という考えもあり。
ただ、対応すると開発時不便そうなのと、使用しているノベルツール(Naninovel)が、リソースの管理でがっつり Addressable を利用しているため、あくまで可能ならやる。の範囲で。
アプリ内での呼び出し方
上記のような考え方で設計したうえで、アプリ側の読み出し方法の実装の考え方、ですが。
アプリ内部での呼び出し方は、全てのアセットにおいて、Addressable の仕組みをベースに同一の呼び方で取得可能な仕組みを作ります。
例えば、以下のような形でテキスト、プレハブ含む全てのアセットを取得可能にします。
Texture2D texture = await apiCliant.GetAssetAsync<Texture2D>(ASSET_PATH);
こちらも具体的な実装方法は、後日別記事で紹介したいと思います。
最後に
まあ、書いててすでに一筋縄でいかない感をゴリゴリ感じていますが、ひとつづつ解決していきましょう 笑。
これらの実装は、実際のゲームを作りながら必要になった箇所から行っています。
いつ土台が完成するのか? 夏にはある程度できてたいなぁ。
そんな感じで、では!