104.9K Views
November 06, 19
スライド概要
発表者: 郷津風さま(ソレイユ株式会社)
本スライドは2019年10月31日に行われた勉強会「 UE4 Localization Deep Dive」の講演資料となります。ソレイユ様、このような貴重な情報を一般に公開していただきまことにありがとうございます!
Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/
最新UE4タイトルでの ローカライズ事例 ソレイユ株式会社 エンジニア 郷津 風 2019/10/31
目次 • 自己紹介 • 事前情報 • 概要 • 実装手順(StringTable, LocalizationDashboard, Blueprint) • 設定手順(Config,C++側) • 応用編(設定,字幕) • 注意点 • まとめ
自己紹介
自己紹介 • 郷津 風(ごうづ ふう) • エンジニア • 元 Webのサーバエンジニア • 現 ゲームのプログラマ • 直近 • • • • UI全般 多言語対応 プラットフォーム対応 とかとか
事前情報
事前情報 • 三人称視点のシングルプレイ アクションゲーム • UE4のバージョンは4.20->4.22 • 新しいバージョンが出る度に調査してからアップデート • 多少のバージョンアップによる問題は力づくで対応 (シーケンサーとかシーケンサーとかシーケンサーとか)
事前情報 • 対応した言語は10言語 言語 言語タグ 言語 言語タグ 英語 en 日本語 ja フランス語 fr ドイツ語 de フランス語 (カナダ) fr-CA 中国語 (簡体字) zh-Hans スペイン語 es ロシア語 ru スペイン語 (ラテンアメリカ) es-419 ポルトガル語 (ブラジル) pt-BR ※ゲームの言語設定はコンソールの設定を反映
事前情報 • 対応した言語は10言語 言語 言語タグ 英語 en フランス語 fr フランス語 (カナダ) fr-CA スペイン語 es スペイン語 (ラテンアメリカ) es-419 何が違うのかわからない…
事前情報-おまけ フランス語(カナダ)• フランス語(カナダ)とは… • ケベック州で話されケベコアと呼ばれる 日本語 フランス語 ケベコア ガード Blocage Parade ロングソード Broadsword Épée à deux mains デバッグ Débogue Débogage 翻訳者のさじ加減 のような気もする
事前情報 • ローカライズの対象 • • • • テキスト全般 アセット(フォントのみ) 決定、キャンセルボタンの位置 ※音声は非対応
事前情報 • 対応したプラットフォームは4つ • • • • PS4 XboxOne Nintendo Switch Steam
事前情報 • Widget Blueprintについての知識 • LocalizationDashboardについての知識 • Localizationの公式ドキュメント (https://docs.unrealengine.com/enUS/Gameplay/Localization/index.html)
概要
概要-ポイント• LocalizationDashboardだけを使っている • デフォルト言語に”使わない言語”を設定 • 追加・編集が簡単、動作が確認しやすい
概要-ポイント• LocalizationDashboardだけを使っている • 自社ツール、素敵なシステムは一切使っていない • 問題が起こったらEngineのコードいじって対応
概要-ポイント• デフォルト言語に”使わない言語”を設定 • パブリッシャーが海外→デフォルト言語は日本語にできない • 翻訳データは頻繁に更新されるもの • LocalizationDashboardにおいて、 デフォルト言語の翻訳変更はクリティカル!!!!! ※後ほど解説
概要-ポイント• 追加・編集が簡単、動作が確認しやすい あのテキストも必要だった 追加して 翻訳変わったからよろしく 企画 翻訳追加になったから やっといて ここ字幕も出したいんだけど このテキストの 全言語翻訳ください 最大文字数いくつですか? はみ出し確認したいんですけど アート
概要-ポイント• 追加・編集が簡単、動作が確認しやすい あのテキストも必要だった 追加して 翻訳変わったからよろしく 企画 翻訳追加になったから このテキストの 全言語翻訳ください プログラマだけでは対応しきれない!!! やっといて ここ字幕も出したいんだけど 最大文字数いくつですか? はみ出し確認したいんですけど アート
概要-ポイント• 追加・編集が簡単、動作が確認しやすい • どのセクションの人でも簡単に確認・設定できる • • • • 企画 :どの部分にテキストを表示するか決める レベル :レベルギミックでテキストを表示したい アニメーター :字幕表示したい UIアーティスト:表示される最大文字数を確認したい : テキスト・翻訳の追加方法、テキストの確認方法を ドキュメント化しておけばプログラマの仕事が減る
概要-実装の流れ• StringTableにローカライズタグを設定 • LocalizationDashboardの作業 • • • • ターゲットの追加 カルチャーの追加 テキストの収集→翻訳→コンパイル (テキストのインポート/エクスポート) • Widgetにローカライズタグをセット
概要-実装の流れ• StringTableにローカライズタグを設定 →ローカライズ対象となるテキストを一覧で用意する Widgetにセット するときに使う ローカライズタグ としてデフォルト 言語に収集される
概要-実装の流れ• LocalizationDashboardの作業 →ローカライズ対象のテキストを集めて翻訳データを設定する LoadingPolicyの設定(翻 訳のタイミング)→Always 翻訳対象の収集先設定 →StringTable ターゲットの追加(翻訳 データのまとまり) 翻訳言語に対する操作
概要-実装の流れ• Widgetにローカライズタグをセット →翻訳データが紐付いたローカライズタグを設定する StringTableのNamespaceと Keyで翻訳データを取得
実装手順(エディタ側)
実装手順-LocalizationDashboardの仕組み• デフォルト言語1つに対して、各種言語の翻訳データが紐づく デフォルト言語 英語 日本語 ドイツ語 ロシア語 フランス語
実装手順-LocalizationDashboardの仕組みHello GutenTag こんにちは Здравствуйте 「こんにちは」に「Hello」や「GutenTag」が 紐付いている Bonjour
実装手順-LocalizationDashboardの仕組み??? ??? ご機嫌いかが? ??? 「こんにちは」から「ご機嫌いかが?」に書き換 えられると、紐付いていたテキストが切られる ???
実装手順-LocalizationDashboardの仕組み• デフォルト言語1つに対して、各種言語の翻訳データが紐づく →使用しない言語をデフォルト言語にして固定する デフォルト言語 日本語 選定した言語 英語 ドイツ語 ロシア語 フランス語
実装手順-LocalizationDashboardの仕組みこんにちは Hello Knight_Greeting_01 GutenTag ローカライズタグに各言語の翻訳が紐付いている Здравствуйте
実装手順-LocalizationDashboardの仕組みご機嫌いかが? How Are You? Knight_Greeting_01 GutenTag 各言語の翻訳が変更されてもローカライズタグは 変わらないので紐付けが切られない Здравствуйте
実装手順-LocalizationDashboardの仕組み完成しているゲームに対して LocalizationDashboardで対応 開発中のゲームに対して LocalizationDashboardで対応 →デフォルト言語が書き換わらないた め、LocalizationDashboardを使うこと で簡単に多言語対応が可能 →使いづらい。デフォルト言語の翻訳 が変わるとややこしくなるので工夫が 必須(デフォルト言語に使わない言語を 設定するなど)
実装手順-実装の流れ• StringTableにローカライズタグを設定 • LocalizationDashboardの作業 • • • • ターゲットの追加 カルチャーの追加 テキストの収集→翻訳→コンパイル (テキストのインポート/エクスポート) • Widgetに設定
実装手順-ローカライズタグ設定-
実装手順-ローカライズタグ設定- Namespace... Dashboard上にテキストが収集されたときにここ がソートの基準になるので意外と重要
実装手順-ローカライズタグ設定- Key:Namespace内でプライマリ SourceString:翻訳対象のテキストだが、ローカ ライズタグとして扱う。
実装手順-ローカライズタグ設定- CSV形式でImport/Exportが可能なのでExcelとか でも管理ができる
実装手順-StringTableの運用ルール• アセット名とNamespace名 • ST_XXXXX • KeyとSourceString Namespace内で、 ・Key:プライマリ ・SourceString:セカンダリ ではあるが、Namespaceの垣根なく両方 ともプライマリであったほうが後々便利 • 基本的に同じ文字列(※例外あり) • アイテム名などある程度決まっているものは開発名 • NPCの会話などまったく未定なものは連番をふったもの • 字幕は表示箇所別のタグ+ボイスの喋りだし数単語をつけたもの
実装手順-実装の流れ• StringTableにローカライズタグを設定 • LocalizationDashboardの作業 • • • • ターゲットの追加 カルチャーの追加 テキストの収集→翻訳→コンパイル (テキストのインポート/エクスポート) • Widgetに設定
実装手順-LocalizationDashboard• GameTargetsの追加 →総合的にみるとターゲットは少ないほうがいい
実装手順-LocalizationDashboard• どこからテキストを収集するか設定 →ターゲット毎にStringTableのディレクトリを分けておく
実装手順-LocalizationDashboard• デフォルト言語を選定して追加 →ローカライズ対象以外の言語を設定する
実装手順-LocalizationDashboard• Gather->翻訳->Compile
実装手順-LocalizationDashboard• デフォルト言語の編集画面 Source : StringTableから収集されたテキスト Translation : デフォルト言語の翻訳(ローカライズタグ)
実装手順-LocalizationDashboard• 日本語の編集画面 Source : デフォルト言語の翻訳(ローカライズタグ) Translation : 日本語の翻訳データ
実装手順-LocalizationDashboard• 翻訳 →poファイル形式でインポート/エクスポートも可能
実装手順-おまけ .poファイル• Portable Object file • 翻訳用のファイル形式(.pot, .mo などの仲間) • Key:Value形式で翻訳データの入力が可能 • 1つのGameTargetにつき、1言語1poファイルができる UI (GameTarget) UI.po UI.po UI.po (デフォルト言語) (日本語) (ドイツ語)
実装手順-おまけ .poファイル• .poファイルの中身
実装手順-おまけ .poファイル• Poedit(poファイル編集用の無料ツール)
実装手順-LocalizationDashboard• 翻訳 →poファイル形式でインポート/エクスポートも可能 Gather→Export→翻訳→Import→Compile 企画 Publisher 企画
実装手順-LocalizationDashboard• 翻訳 →poファイル形式でインポート/エクスポートも可能 1ターゲット(計2000ワード)にコンパイル -> 10分 5ターゲット(計2000ワード)にコンパイル -> 50分 →ワード数ではなくターゲット数に比例して時間がかかる
実装手順-GameTargetsの運用ルール• ターゲットの粒度 • ローカライズタグがプライマリにできるくらい • なるべくターゲットは増やさない • ターゲットに設定するStringTableの分類 • 更新頻度が高くなりそうなものはまとめる(無理) • StringTableはターゲット毎にディレクトリをわける ※全ターゲットの翻訳データを一括で操作していたため、このよ うな運用になった。更新されるターゲット数が少ないのであれば 必ずしも少なくする必要はない。
概要-実装の流れ• StringTableにローカライズタグを設定 • LocalizationDashboardの作業 • • • • ターゲットの追加 カルチャーの追加 テキストの収集→翻訳→コンパイル (テキストのインポート/エクスポート) • Widgetに設定
組み込み-Widgetに設定• 後から書き換える必要がない場合 →WidgetのUMG側で設定
組み込み-Widgetに設定• 後から書き換える必要がない場合 →WidgetのUMG側で設定
組み込み-Widgetに設定• 後から書き換える必要がない場合 →WidgetのUMG側で設定 設定するとエディタの設定言語に即時翻訳される ため、長さやサイズ感を確認しながら作業可能 ※フォントのローカライズはされないので注意!
組み込み-Widgetに設定• 後から書き換える必要がある場合 →WidgetのBlueprint側で設定
組み込み-Widgetに設定• 後から書き換える必要がある場合 →WidgetのBlueprint側で設定
組み込み-Widgetに設定• マスターデータから設定 →FindTextInLocalizationTable()を使用する
ローカライズの流れまとめ • StringTableのSourceStringがデフォルト言語のSourceになる StringTableの編集画面 デフォルト言語の編集画面
ローカライズの流れまとめ • デフォルト言語のTranslationが翻訳対象のSourceになる デフォルト言語の編集画面 翻訳対象言語の編集画面
ローカライズの流れまとめ • WidgetにStringTableのKeyを設定すると、翻訳対象の Translationが表示される StringTableの編集画面 翻訳対象言語の編集画面
設定手順(Config,C++側) デフォルト言語に”使わない言語”を設定したことによる問題の解決
設定手順-おまけ 言語タグ言語 言語タグ 言語 言語タグ 英語 en 日本語 ja フランス語 fr ドイツ語 de フランス語 (カナダ) fr-CA 中国語 (簡体字) zh-Hans スペイン語 es ロシア語 ru スペイン語 (ラテンアメリカ) es-419 ポルトガル語 (ブラジル) pt-BR
設定手順-おまけ 言語タグ• 言語タグってなに? language - script - region -… 言語 文字体系 地域 • ハイフンによって接続された、 言語に関する下位タグの集まりのこと
設定手順-おまけ 言語タグ• 言語タグの使い方は結構自由! • よく使われるスタイル • language下位タグのみ : ja, en, de,… • language-region : en-UK, en-US, pt-BR,… • その他スタイル • language-script-region : zh-Hans-CN,…
設定手順-CultureMappingの変更Windows10の設定画面 オーストラリア英語の言語タグはen-AU
設定手順-CultureMappingの変更あっ…
設定手順-CultureMappingの変更• 検出された言語がデフォルト言語だった場合、ローカライズタ グが表示されてしまう SettingCulture = en-AU ViewCulture = en-AU そうなっちゃいますよね
設定手順-CultureMappingの変更• 検出された言語がデフォルト言語だった場合、ローカライズタ グが表示されてしまっていた!! • さらに…
設定手順-CultureMappingの変更言語 言語タグ 言語 言語タグ 英語 en 日本語 ja フランス語 fr ドイツ語 de フランス語 (カナダ) fr-CA 中国語 (簡体字) zh-Hans スペイン語 es ロシア語 ru スペイン語 (ラテンアメリカ) es-419 ポルトガル語 (ブラジル) pt-BR アルゼンチンとかチリとかではスペイン 語(ラテンアメリカ)を表示してほしい… ポルトガルではポルトガル語(ブラジ ル)を表示してほしい…
設定手順-CultureMappingの変更• 検出された言語がデフォルト言語だった場合、ローカライズタ グが表示されてしまう • さらに… • 検出された言語がローカライズ対象じゃないときは、 Publisherの要望に沿った言語に書き換える必要がでた!
設定手順-CultureMappingの変更• 翻訳対象ではない言語が設定されていた場合、 設定された言語のlanguage下位タグの翻訳になる en en-UK en-US 翻訳あり en-AU 翻訳なし en-US設定 → en-USの翻訳 en-UK設定 → enの翻訳 en-AU設定 → enの翻訳
設定手順-CultureMappingの変更• enとen-AU(デフォルト言語)の翻訳データがある場合 en 翻訳あり 翻訳なし こうしたい en-UK en-US en-AU en-UK, en-USの設定のときはenの翻訳 に自動的なるが、en-AUのときもenの翻 訳にしてほしい!
設定手順-CultureMappingの変更• エンジンとConfigに処理を追加 • Config 自前のCultureMappingの設定を記述 • EngineCode 検出した言語をCultureMappingに登録されている言語で 上書き
設定手順-CultureMappingの変更• ~¥XXXX¥Config¥_Platform_¥_Platform_Game.ini [Internationalization.CultureMappings] en-AU=en • Internationalization.CultureMappingは検出用の文字列 • 検出された言語がen-AUのときにenに変更する • 左辺は各プラットフォーム側の言語タグ(※UE4の言語タグとは異なる 可能性があるので、プラットフォームのドキュメント参照) • 右辺はUE4側の言語タグ
設定手順-CultureMappingの変更• ¥UE4¥Engine¥Source¥Runtime¥Core¥Private ¥Internationalization¥TextLocalizationManager.cpp • ReadSettingsFromConfigにCultureMappingsの 取得処理を追加 • 検出された言語のバリデート処理が入る前でCultureMappings を照らし合わせて上書きする
設定手順-CultureMappingの変更• ¥UE4¥Engine¥Source¥Runtime¥Core¥Private ¥Internationalization¥TextLocalizationManager.cpp
設定手順-CultureMappingの変更• 社内に書き換えのノウハウがあったため、それを少しアレンジ して流用 • ※UE4公式の書き換え方法もあります。 (https://dq8iqaixvew1d.cloudfront.net/enUS/Gameplay/Localization/ManageActiveCultureRuntime/index.html#cultureremapping)
設定手順-FallbackCultureの設定• 検出した言語がローカライズ対象外の言語の場合、デフォルト 言語がそのまま表示されてしまう SettingCulture = it ViewCulture = en-AU そうなっちゃいますよね
設定手順-FallbackCultureの設定•例 日本語(ja) こんにちは 英語(en) デフォルト言語(en-AU) Hello Knight_Greeting_01 ロシア語(ru) Здравствуйте フランス語(fr) Bonjour
設定手順-FallbackCultureの設定•例 language=ru で起動 (本体設定をロシア語で起動) 日本語(ja) こんにちは 英語(en) デフォルト言語(en-AU) Hello Knight_Greeting_01 ロシア語(ru) Здравствуйте フランス語(fr) Bonjour
設定手順-FallbackCultureの設定•例 language=it で起動 (本体設定をイタリア語で起動) 日本語(ja) こんにちは 英語(en) デフォルト言語(en-AU) Hello Knight_Greeting_01 ロシア語(ru) Здравствуйте フランス語(fr) Bonjour
設定手順-FallbackCultureの設定• エンジンとConfigに処理を追加 • Config 翻訳対象外の言語が選択されたとき用の言語を設定 • EngineCode 翻訳対象外を検出し設定された言語で上書き
設定手順-FallbackCultureの設定• ~¥XXXX¥Config¥_Platform_¥_Platform_Game.ini [Internationalization] FallbackCulture=en • InternationalizationとFallbackCultureは検出用の文字列 • 翻訳対象外の言語時にenで上書きする
設定手順-FallbackCultureの設定• ¥UE4¥Engine¥Source¥Runtime¥Core¥Private ¥Internationalization¥TextLocalizationManager.cpp • ReadSettingsFromConfigにFallbackCultureの取得処理を追加 • FallbackLanguageがデフォルト言語に設定される処理がある ので、そこで自前のFallBackCultureが設定されていればそち らを優先するように処理追加 • ※FallbackLanguageは元々UE4にある変数
設定手順-FallbackCultureの設定• ¥UE4¥Engine¥Source¥Runtime¥Core¥Private ¥Internationalization¥TextLocalizationManager.cpp
応用-設定編-
応用-1つのキーに対して複数の値• マスターデータに複数の翻訳キーを持たせるのはややこしい… →IDなどに紐づくキーに関しては別々に用意する必要はない かさばりがちなマスターデータのカラムを削減
応用-1つのキーに対して複数の値- ItemAの名前 ItemA (開発名など) ItemAの説明 こっちをキーにする
応用-1つのキーに対して複数の値• NamespaceとSourceStringを分けKeyは同じにする
応用-1つのキーに対して複数の値• NamespaceとSourceStringを分けKeyは同じにする Namespaceが異なるため_Nameや_Infoは付ける必要はないが、これらの SourceStringをダッシュボードで同じターゲットにしてテキストを収集す るとSourceStringが混ざってややこしいので_Nameとか_Infoを付ける →翻訳やデバッグのわかりやすさを考慮
応用-1つのキーに対して複数の値• マスターからキーを取得してNameSpaceだけ指定する
応用-翻訳内の一部を可変させる• テキストの一部分を可変的に扱いたい ローカライズタグを削減
応用-翻訳内の一部を可変させる• 翻訳データ側に識別用のテキストをおいてもらって検出し、 参照したパラメータに置き換える Task_DefeatEnemy String = 敵を[n]体倒す Array[] = {‘敵を’, n, ‘体倒す’} String = 敵を10体倒す n=10 マスターから取得 翻訳データ取得 翻訳データを分解して 可変部分を検出 置き換えて出力
応用-翻訳内の一部を可変させる• 翻訳データ側に識別用のテキストをおいてもらって検出し、 参照したパラメータに置き換える Task_DefeatEnemy String = 敵を[n]体倒す Array[] = {‘敵を’, n, ‘体倒す’} String = 敵を10体倒す FindTextInLocalizationTable() n=10 マスターから取得 翻訳データ取得 翻訳データを分解して 可変部分を検出 置き換えて出力
応用-翻訳内の一部を可変させる• 翻訳データ側に識別用のテキストをおいてもらって検出し、 参照したパラメータに置き換える Task_DefeatEnemy String = 敵を[n]体倒す Array[] = {‘敵を’, n, ‘体倒す’} ParseIntoArray() Split() String = 敵を10体倒す n=10 マスターから取得 翻訳データ取得 翻訳データを分解して 可変部分を検出 置き換えて出力
応用-翻訳内の一部を可変させる• 翻訳データ側に識別用のテキストをおいてもらって検出し、 参照したパラメータに置き換える Task_DefeatEnemy String = 敵を[n]体倒す Array[] = {‘敵を’, n, ‘体倒す’} String = 敵を10体倒す Append() n=10 マスターから取得 翻訳データ取得 翻訳データを分解して 可変部分を検出 置き換えて出力
応用-翻訳内の一部を画像にする• チュートリアルなど、文章中にボタンの画像を入れたい!
RichTextBlock? なにそれ? 参考: https://www.unrealengine.com/ja/tech-blog/advanced-text-styling-with-rich-text-block https://docs.unrealengine.com/en-US/Engine/UMG/UserGuide/UMGRichTextBlock/index.html
応用-翻訳内の一部を画像にする• チュートリアルなど、文章中にボタンの画像を入れたい! • ただこれには問題が…
応用-翻訳内の一部を画像にする• 画像を入れるとUE4のテキストボックスの機能 [AutoWrapText]は使えなくなる!! • それでもいい!とにかく文章中に画像を入れたいんだ!! 改行は翻訳側に明示するから画像を入れさせてくれ!!
応用-翻訳内の一部を画像にする• VerticalBox内に明示的に改行された数だけHorizontalBoxを作る
応用-翻訳内の一部を画像にする• HorizontalBox内にテキストと画像を詰めていく
応用-翻訳内の一部を画像にする• 処理の流れ • • • • • 翻訳データから画像の識別テキストを検出 テキスト部分と画像部分がわかるように配列に格納 テキストや画像を作りながらHorizontalBoxに詰める 改行用識別テキストの場合はHorizontalBoxを新たに作る VerticalBoxにHorizontalBoxを詰める
応用-翻訳内の一部を画像にする• 翻訳データ側に識別用のテキストをおいてもらって検出する Tutorial_Attack String = ‘普通の攻撃は [Btn_A][BR]強い攻撃は [Btn_B][BR]で出ます’ 識別テキスト Btn_A Btn_B : マスターから取得 翻訳データ取得 Array[] = { ‘普通の攻撃は’, Btn_A, BR, ‘強い攻撃は’, Btn_B, BR, ‘で出ます’ } 翻訳データを分解して 可変部分を検出
応用-翻訳内の一部を画像にする• 識別用テキストによって、HorizontalBoxやテキストや画像を 生成する Array[] = { ‘普通の攻撃は’, Btn_A, BR, ‘強い攻撃は’, Btn_B, BR, ‘で出ます’ } 翻訳データを分解して 可変部分を検出 テキストの生成 画像の生成 普通の攻撃は 強い攻撃は で出ます HorizontalBox の生成 配列の各要素を生成 生成された要素をHorizontalBoxに、 HorizontalBoxをVerticalBoxに格納
応用-翻訳内の一部を画像にする• VerticalBoxの設定用変数 • EVerticalAlignment:VerticalBoxのアライン • HorizontalBoxの設定用変数 • EHorizontalAlignment:HorizontalBoxのアライン • テキストの設定用変数 • SlateFontInfo:フォント、サイズなど • SlateColor:フォントの色 • float x2:テキストの上下の幅(Padding用) • 画像の設定用変数 • Vector2D:画像のサイズ • float x2:画像の左右の幅(Padding用)
応用-Mediaplayerに字幕-
Localized Overlays? Basic Overlays? なにそれ? 公式ドキュメントがない!!!!!
応用-MediaPlayer中に字幕を表示• TimeLineを追加
応用-MediaPlayer中に字幕を表示• TimelineにEventTrackを作成しキーを置く
応用-MediaPlayer中に字幕を表示• キーは横軸が字幕開始タイミング(Valueは適当)
応用-MediaPlayer中に字幕を表示• Mediaの再生とともにTimelineを起動(Play) • Timelineに実行ピンが追加される (Subtitle) • Timeline上の表示タイミングに合 わせて、処理が実行される • 出てきたタイミングで字幕Widget の表示を行う
応用-MediaPlayer中に字幕を表示• 表示する字幕テキストと表示秒数は予め配列で持っておき、カ ウンタ変数で配列番号を指定して表示
注意点
注意点-StringTableの読み込み• マスターデータからキーを取得して表示!
注意点-StringTableの読み込み• あれぇ…? 設定 ローカライズデータがみつからない ローカライズデータがみつからない ローカライズデータがみつからない ローカライズデータがみつからない
注意点-StringTableの読み込み• FindTextInLocalizationTable()を呼ぶだけではロードされない • 変数や初期値に設定するなどしてメモリに読み込 んでおく必要があります。
注意点-デフォルト言語の選定• ローカライズ対象にできる言語は多い(言語タグ)
注意点-デフォルト言語の選定- •ニャンコレ語(nyn) ・響きがかわいい! ・言語タグもかわいい!! • デフォルト言語に採用!!!
注意点-デフォルト言語の選定- •ニャンコレ語(nyn) ・響きがかわいい ・言語タグもかわいい 某コンソールの • デフォルト言語に採用! Buildが通らない
注意点-デフォルト言語の選定• ニャンコレ語(nyn) ・響きがかわいい ・言語タグもかわいい オーストラリア英語 でいいんじゃない? • デフォルト言語に採用! • マイナーすぎる言語は避けましょう。
注意点-GameTargetsの数• GameTargetsを分けて翻訳データの管理をしや すくしよう! • GameTargetsを細かい粒度で設定! 翻訳データを反映するぞ!
注意点-GameTargetsの数• GameTargetsを分けて翻訳データの管理をしや すくしよう! • GameTargetsを細かい粒度で設定! 翻訳データを反映するぞ! GameTargets数に比例して コンパイル時間が増える
注意点-GameTargetsの数• GameTargetsを分けて翻訳データの管理をしやすくしよう! • GameTargetsを細かい粒度で設定! • むやみに増やさないようにしましょう。
注意点-デフォルトターゲットの扱い• デフォルトで用意されているターゲットGame
注意点-デフォルトターゲットの扱い- • 自分たちの任意の粒度でターゲットを設定 しよう! • デフォルトであったターゲットGameは使わない!削除!
注意点-デフォルトターゲットの扱い- • 自分たちの任意の粒度でターゲットを設定 しよう! パッケージに翻訳データが 一切入らなくなる • デフォルトであったターゲットGameは使わない!削除!
注意点-デフォルトターゲットの扱い• パッケージの設定を確認してみたところ…
注意点-デフォルトターゲットの扱い• パッケージングの設定を確認してみたところ… 翻訳対象の言語に黄色い ビックリマークがついてる
注意点-デフォルトターゲットの扱い• パッケージングの設定を確認してみたところ… • どうやら他にターゲットがあっても、デフォルトターゲットの Gameからローカライズ言語を取得しているらしい…
注意点-デフォルトターゲットの扱い• 自分たちの任意の粒度でターゲットを設定 • デフォルトであったターゲットGameいらない!削除! • 削除しないで最低限の状態でおいておきましょう。
まとめ
まとめ • UE4だけでローカライズを実装! • デフォルト言語に”使わない言語”を設定することで翻訳データ の変更に強い実装になった →要エンジンの改造 • タグの追加(StringTable)、ローカライズの確認(UE4Editor)、 タグのセット(Blueprint,C++)が誰でも容易 →要ワークフロー整備、ドキュメント化
まとめ • UE4だけでローカライズを実装! • デフォルト言語に”使わない言語”を設定することで翻訳データ の変更に強い実装になった • タグの追加(StringTable)、ローカライズの確認(UE4Editor)、 タグのセット(Blueprint,C++)が誰でも容易 • 新しい機能の追加や隠された機能の情報には敏感に!!
おまけもあるよ!
本編に入らなかったおまけ
地域によるボタンの入れ替え • 日本では決定ボタンは右ボタンがオーソドックスだが、他国で は下ボタンが多い
地域によるボタンの入れ替え • FPlatformInput::GetGamepadAcceptKey().GetFName() • Gamepad_FaceButton_Bottom • Gamepad_FaceButton_Left • 決定ボタンの位置が分かれば、それに合わせてKeyMapを書き 換えるだけ!
ローカライズの対象 • ゲームのタイトル画面での「Press Any Button」 • 新しいコンテンツが追加されたときの「New」 • などなど… • 英語→日本語に”あえてしない”という選択肢もある。 ゲームの雰囲気やゲームの年齢層に沿ってローカライ ズ対象を決めるのがいい(フランス語圏は知らない)
おまけもあるよ! ほろかわいい!