これまでにTheRoomの2・3・4をXUnity.AutoTranslatorで日本語化(自動翻訳化)することができました。差し当たり、これで私が日本語化(自動翻訳化)したいゲームはなくなりました。しばらく経って、また自分で日本語化(自動翻訳化)したいゲームが出た頃には今回のことで得た知識を忘れていそうな気がするので新規ゲームへXUnity.AutoTranslatorをセットアップをする場合にどこを見て何を判断すれば良いのか?という視点で再度情報をまとめたいと思います。
(忘れる程時間が経っていると各種ツールのバージョンが上がっていて、これまでのやり方が通じなくなっていた…なんて事は良くあるので無駄になるかも知れませんが…)
もし『Unity以外』だった場合はXUnity.AutoTranslatorを利用できないのでこの記事の対象外となります。
またBepInExが提供してくれる機能で特に重要なのが外部コード(プラグイン)をゲーム内部で動作させる(ロードする)機能で、この機能を持つプログラムは『ローダー』と呼ばれることがあります。
XUnity.AutoTranslatorは様々なローダーに対応しているようですが、BepInExが推奨とありますのでそれに従いBepInExをインストールします。 インストールするファイルはUnityの種類によって変わってきます。2023年6月時点での最新版は下記のとおりです。
使用するファイルは特別な理由のない限り最新のリリース版で良いと思います。ただIL2CPPはBepInEx6からのサポートで、BepInEx6のリリース版が現時点ではありません。
そのためIL2CPPはプレリリース版を使用します。(プレリリース版よりも新しいbe版もありますが現時点でXUnity.AutoTranslatorは最新be版に対応していません。pre版と最新be版はnamespaceがBepInEx.IL2CPPとBepInEx.Unity.IL2CPPで異なっていることもありプラグインが未対応だと動作しません。)
インストール方法
通常どおりにゲームが起動しない場合:
こちらもインストールするのは基本的に最新リリース版で良いと思います。
インストール方法
設定変更後、ゲームを起動しメインメニューなど英語表示のある画面まで進み、しばらく(~1分程)待ちます。
これはゲーム内のフォントを日本語表示可能なフォントへ変更すれば解消することができます。
またドキュメントによればテキストフレームワークが UGUI の場合でも設定ファイルを変更すればフォントを変更できるようです。しかし、こちらは使用したことがないので本記事では扱いません。(設定ファイルの"OverrideFont="で指定可能。コードを流し見る限りWindowsにインストール済のフォント名を指定するようです。)
③は いわゆる日本語化MODで、ゲームを解析してリソース(場合によってはコードも)を変更し日本語表示可能なフォントにする方法です。ゲーム毎の解析が必要なので本記事では扱いません。
②はTheRoom2,3で行った方法で①と③の中間です。TheRoom2を日本語表示させようとdnSpyで適当にイジっていたらNGUIでの日本語表示可能なフォントの簡単な作成方法がわかったのでXUnity.AutoTranslatorを改造して実装した…という方法です。
ゲームを起動し日本語が表示されない(消えた/□になった)画面まで進みゲーム内の操作でゲームを終了。ログを確認します。
本記事ではこの2種類だけですが、これ以外のクラス名であっても クラス名 + Unity で検索すればテキストフレームワークの判定は可能だと思います。
この後はテキストフレームワーク毎の対応となります。なおTextMeshPro、NGUI以外はわからないので本記事では扱えません。(UGUIは前述の通り"OverrideFont="で何とかなるかも??)
ゲームを起動し日本語が表示されなかった画面まで進みます。
(忘れる程時間が経っていると各種ツールのバージョンが上がっていて、これまでのやり方が通じなくなっていた…なんて事は良くあるので無駄になるかも知れませんが…)
目次
1. Unityの判断(Unity以外, x86/x64, Mono/IL2CPP)
XUnity.AutoTranslatorはUnityというゲームエンジンが使用されているゲームでなれば利用することが出来ません。このUnityには種類があり、ゲームが使用しているUnityの種類に合わせたBepInEx(後述)をインストールする必要があるためUnityの種類をまずは判断する必要があります。※お使いのパソコンやOSのことではありません。ゲームがどの種類のUnityを使用しているかを判断します。
その判断方法は下記のとおりです。(いつも『何となく』で判断していたので、改めて記載するとあまり自信がありませんが…)
種類 | 判断方法(条件) |
---|---|
Mono x86 | game_Data というフォルダがある game_Data\Managed というフォルダがある game.exe が32bitである |
Mono x64 | game_Data というフォルダがある game_Data\Managed というフォルダがある game.exe が64bitである |
IL2CPP x86 | game_Data というフォルダがある game_Data\il2cpp_data というフォルダがある game.exe が32bitである ※私はこの種類のゲームを見たことがありません |
IL2CPP x64 | game_Data というフォルダがある game_Data\il2cpp_data というフォルダがある game.exe が64bitである |
Unity以外 | 上記以外 |
※対象ゲームの実行ファイルを"game.exe"と仮定します。
TheRoom4であれば"OldSins.exe"という実行ファイル名で"OldSins_Data"というフォルダが存在します。
TheRoom4であれば"OldSins.exe"という実行ファイル名で"OldSins_Data"というフォルダが存在します。
※実行ファイルが32bitか64bitかの判断はこちらをご覧ください。
※私が遊んだことのあるゲームは上記条件にあうものしかありませんでしたが、場合によっては外れるゲームがあるかも知れません。
2. BepInExのインストール
BepInExはMOD(プラグイン)に共通して必要となる様々な機能を提供してくれるMODで、このようなプログラムは『前提MOD』と呼ばれることがあります。またBepInExが提供してくれる機能で特に重要なのが外部コード(プラグイン)をゲーム内部で動作させる(ロードする)機能で、この機能を持つプログラムは『ローダー』と呼ばれることがあります。
XUnity.AutoTranslatorは様々なローダーに対応しているようですが、BepInExが推奨とありますのでそれに従いBepInExをインストールします。 インストールするファイルはUnityの種類によって変わってきます。2023年6月時点での最新版は下記のとおりです。
使用するファイルは特別な理由のない限り最新のリリース版で良いと思います。ただIL2CPPはBepInEx6からのサポートで、BepInEx6のリリース版が現時点ではありません。
そのためIL2CPPはプレリリース版を使用します。(プレリリース版よりも新しいbe版もありますが現時点でXUnity.AutoTranslatorは最新be版に対応していません。pre版と最新be版はnamespaceがBepInEx.IL2CPPとBepInEx.Unity.IL2CPPで異なっていることもありプラグインが未対応だと動作しません。)
種類 | ファイル |
---|---|
Mono x86 | BepInEx_x86_5.4.21.0.zip |
Mono x64 | BepInEx_x64_5.4.21.0.zip |
IL2CPP x86 | BepInEx_UnityIL2CPP_x86_6.0.0-pre.1.zip |
IL2CPP x64 | BepInEx_UnityIL2CPP_x64_6.0.0-pre.1.zip |
・zipファイルの解凍およびファイル配置
上記zip内のwinhttp.dllとgame.exeが同じフォルダになるように解凍(または解凍後に移動)します。
・BepInExの有効化を確認
通常どおりにゲーム(game.exe)を起動しゲーム内の操作で終了します。
その後エクスプローラー等で"BepInEx\LogOutput.log"(ログファイル)が作成されているかを確認します。
作成されていればメモ帳等で開き重要そうなエラーがないかを確認します。
特に重要そうなエラーがなければBepInExのインストールは完了です。
その後エクスプローラー等で"BepInEx\LogOutput.log"(ログファイル)が作成されているかを確認します。
作成されていればメモ帳等で開き重要そうなエラーがないかを確認します。
特に重要そうなエラーがなければBepInExのインストールは完了です。
ゲーム内の操作が効かなくなっている場合は[Alt]+[F4]やタスクマネージャなどでゲームを終了させます。
BepInExのトラブルシューティングに沿って解決を試みます。
(実際にTheRoom2では真っ暗な画面で先に進まなくなりました。こちらに記載されているとおり"BepInEx/config/BepInEx.cfg"の[Preloader.Entrypoint]のTypeをMonoBehaviourへ変更したら解決しました。)
ログファイルが作成されない場合:
BepInExのトラブルシューティングに沿って解決を試みます。
(実際にTheRoom2では真っ暗な画面で先に進まなくなりました。こちらに記載されているとおり"BepInEx/config/BepInEx.cfg"の[Preloader.Entrypoint]のTypeをMonoBehaviourへ変更したら解決しました。)
ファイルの配置が正しいか(解凍して得られたwinhttp.dllやBepInExフォルダがgame.exeと同じフォルダになっているか?)を再度確認してください。
またUnityの種類(x86/x64, Mono/IL2CPP)とインストールしたzipファイルもあっているか再度確認してください。
間違いが見つからない場合トラブルシューティングに有益な情報がないか探してみてください。
ログに重要そうなエラーがあった場合:
またUnityの種類(x86/x64, Mono/IL2CPP)とインストールしたzipファイルもあっているか再度確認してください。
間違いが見つからない場合トラブルシューティングに有益な情報がないか探してみてください。
トラブルシューティングに有益な情報がないか探します。
また残っているエラーメッセージで検索し解決策がないかを調べます。
また残っているエラーメッセージで検索し解決策がないかを調べます。
※どうしてもBepInExのインストールに失敗する場合はスタンドアロン版(ReiPatcher)のXUnity.AutoTranslatorを試すという手もあります。
3. XUnity.AutoTranslatorのインストール
続いてインターネットの翻訳サービスを用いてゲーム内テキストの翻訳をしてくれるMOD、XUnity.AutoTranslatorをインストールします。 インストールするファイルはBepInEx版で例によってUnityの種類によって変わってきます(しかしx86とx64は区別なし)。2023年6月時点での最新版は下記のとおりです。こちらもインストールするのは基本的に最新リリース版で良いと思います。
種類 | ファイル |
---|---|
Mono x86 Mono x64 |
XUnity.AutoTranslator-BepInEx-5.2.0.zip |
IL2CPP x86 IL2CPP x64 |
XUnity.AutoTranslator-BepInEx-IL2CPP-5.2.0.zip |
・zipファイルの解凍およびファイル配置
BepInExのインストールで既にできているBepInExフォルダと上記zip内のBepInExフォルダが一致するように解凍(または解凍後に移動)します。
・XUnity.AutoTranslatorの有効化を確認
通常どおりにゲームを起動しゲーム内の操作で終了します。
その後エクスプローラー等で"BepInEx\LogOutput.log"(ログファイル)を開き"[Info :XUnity.AutoTranslator]"から始まる行があればXUnity.AutoTranslatorのインストールは完了です。
(翻訳サービスに接続できないだけでもエラーになるのでXUnity.AutoTranslatorのエラーはここでは無視します)
その後エクスプローラー等で"BepInEx\LogOutput.log"(ログファイル)を開き"[Info :XUnity.AutoTranslator]"から始まる行があればXUnity.AutoTranslatorのインストールは完了です。
(翻訳サービスに接続できないだけでもエラーになるのでXUnity.AutoTranslatorのエラーはここでは無視します)
4. XUnity.AutoTranslatorの基本設定および効果確認
下表のとおり設定ファイルを書き換えます。設定ファイル:BepInEx\config\AutoTranslatorConfig.ini | |
項目 | 変更理由等 |
---|---|
[Service] Endpoint=DeepLTranslate |
翻訳サービスを指定します。GoogleTranslateV2がデフォルトになっていますが私の環境ではかなり高確率で失敗するのでDeepLTranslateにしています。ここはご自身の環境や好みで読み替えてください。 |
[General] Language=ja FromLanguage=en |
翻訳先・翻訳元の言語指定です。デフォルトでは日本語→英語になっているので英語→日本語へ変更します。 |
日本語が表示された
日本語化(自動翻訳化)完了です。場合によっては翻訳に関係する設定を変更(長文が翻訳されないときはMaxCharactersPerTranslationを増やすなど)する必要があるかも知れませんが基本的にはこのまま翻訳された日本語で遊ぶことができるはずです。
また[Alt]+[T]で原文⇔訳文を切り替えることができるので、英語がアヤしい時などは利用してみてください。
文字が消えた または 文字が□に変わった
また[Alt]+[T]で原文⇔訳文を切り替えることができるので、英語がアヤしい時などは利用してみてください。
日本語への翻訳は成功したがゲーム内のフォントでは日本語表示に対応していないため発生している現象と思われます。「5. XUnity.AutoTranslatorで日本語表示されないときの対応」へ進んでください。
なお、ゲーム中の操作がしづらい場合は[Alt]+[T]で原文に戻して操作してください。
英語のまま変わらない
なお、ゲーム中の操作がしづらい場合は[Alt]+[T]で原文に戻して操作してください。
原因として下記2点が考えられます。(他にもあるかも知れませんが、現在の私には思いつきません)
①XUnity.AutoTranslatorがテキスト(文字)を取得できていない
"Translator"を変更し再度テキストを読み込む為にゲーム中の操作で少し画面を切り替えて(メインメニューからオプションメニューへ行った後にメインメニューに戻るなど)ください。
下図のように"Served translations"が増えれば、そのTranslatorが使用できています。ゲーム画面に何らかの変化(日本語表示された/文字が消えた)が起きているはずなので前述に従ってください。 変更後のTranslatorでも"Translator status"がShutdownになる場合は また別のTranslatorを試したり、そもそもインターネットに接続できるかなどWindowsの設定を見直してみてください。
①XUnity.AutoTranslatorがテキスト(文字)を取得できていない
対象ゲームがXUnity.AutoTranslatorのサポートしていない方式(フレームワーク)でテキスト出力している…などの理由でテキストが取得できていない。
②翻訳ができていない
テキスト取得はできているが翻訳サービスへ接続できない等の理由で翻訳が失敗している。①よりもこちらの方が可能性が高いと思います。
英語のまま変わらない場合はゲーム画面のまま[Alt]+[0]でXUnity.AutoTranslatorのGUIを表示します。
上図のように"Error'ed translations"が5/5で"Translator status"がShutdownになっている場合は、テキスト取得は成功しているが翻訳が失敗している状態です。"Translator"を変更し再度テキストを読み込む為にゲーム中の操作で少し画面を切り替えて(メインメニューからオプションメニューへ行った後にメインメニューに戻るなど)ください。
下図のように"Served translations"が増えれば、そのTranslatorが使用できています。ゲーム画面に何らかの変化(日本語表示された/文字が消えた)が起きているはずなので前述に従ってください。 変更後のTranslatorでも"Translator status"がShutdownになる場合は また別のTranslatorを試したり、そもそもインターネットに接続できるかなどWindowsの設定を見直してみてください。
もしテキスト取得が失敗している場合は上図のように"Plugin status"・"Translator status"ともにRunningで"translations"が4つとも0になっているはずです。
単に今まで表示された画面にテキストがなかった(表示された英語は文字情報ではなく画像だった)だけかも知れないので、オプションメニューへ変えてみたりゲーム本編の画面まで進めて見たりして、ゲーム中で様々な画面を表示させてみます。
それでも"translations"が4つとも0で変わらない場合はゲーム内の操作でゲームを終了しログを確認します。
もし何らかのエラーが残っていた場合はそのエラーによってテキスト取得が失敗しているのかも知れないのでエラー内容を調査します。
また設定ファイル内の[TextFrameworks]の全項目をTrueにして変化があるか?などを試してみます。
単に今まで表示された画面にテキストがなかった(表示された英語は文字情報ではなく画像だった)だけかも知れないので、オプションメニューへ変えてみたりゲーム本編の画面まで進めて見たりして、ゲーム中で様々な画面を表示させてみます。
それでも"translations"が4つとも0で変わらない場合はゲーム内の操作でゲームを終了しログを確認します。
もし何らかのエラーが残っていた場合はそのエラーによってテキスト取得が失敗しているのかも知れないのでエラー内容を調査します。
また設定ファイル内の[TextFrameworks]の全項目をTrueにして変化があるか?などを試してみます。
5. XUnity.AutoTranslatorで日本語表示されないときの対応
XUnity.AutoTranslatorの翻訳結果が表示されない(文字が消える/□が表示される)のはゲーム内のフォントが日本語表示に対応していないために発生しています。これはゲーム内のフォントを日本語表示可能なフォントへ変更すれば解消することができます。
その変更方法として私が知っているのは下記3つとなります。
①XUnity.AutoTranslatorの機能を利用(TextMeshPro または UGUI のみ)
②XUnity.AutoTranslatorを改造して無理やり日本語表示(NGUI のみ)
③ゲームを改造(リソースの変更など)
①はTheRoom4で行った方法でゲームが使用しているテキストフレームワークが TextMeshPro であれば設定ファイルを変更し外部のフォントを読み込むことができます。(100%可能というわけでは無いようです。ゲーム次第だと思います。)①XUnity.AutoTranslatorの機能を利用(TextMeshPro または UGUI のみ)
②XUnity.AutoTranslatorを改造して無理やり日本語表示(NGUI のみ)
③ゲームを改造(リソースの変更など)
またドキュメントによればテキストフレームワークが UGUI の場合でも設定ファイルを変更すればフォントを変更できるようです。しかし、こちらは使用したことがないので本記事では扱いません。(設定ファイルの"OverrideFont="で指定可能。コードを流し見る限りWindowsにインストール済のフォント名を指定するようです。)
③は いわゆる日本語化MODで、ゲームを解析してリソース(場合によってはコードも)を変更し日本語表示可能なフォントにする方法です。ゲーム毎の解析が必要なので本記事では扱いません。
②はTheRoom2,3で行った方法で①と③の中間です。TheRoom2を日本語表示させようとdnSpyで適当にイジっていたらNGUIでの日本語表示可能なフォントの簡単な作成方法がわかったのでXUnity.AutoTranslatorを改造して実装した…という方法です。
どの方法で変更するにしても、まずは対象のゲームがどのテキストフレームワークを使用しているかを判断する必要があります。
5-1. テキストフレームワークの判定
下表のとおり設定ファイルを書き換えます。設定ファイル:BepInEx\config\AutoTranslatorConfig.ini | |
項目 | 変更理由等 |
---|---|
[Behaviour] EnableTextPathLogging=True |
XUnity.AutoTranslatorがテキストを設定する際、その設定対象の情報をログに出力します。ログ出力の頻度が高めなので、ひと通り調査が終わったらFalseに戻すことをおすすめします。 |
例えばTheRoom4ではログに下記が見つかります。XUnity.AutoTranslatorが'TMPro.TextMeshProUGUI'クラスのオブジェクトへテキストを設定しているのでTheRoom4はテキストフレームワークとしてTextMeshProを使用している事がわかります。
[Info :XUnity.AutoTranslator] Setting text on 'TMPro.TextMeshProUGUI' to '現在のプロファイル'
[Info :XUnity.AutoTranslator] Path : /UI Root Canvas (2D)/RootPanel/SelectGamePanel/CurrentProfile/Current Profile Text
[Info :XUnity.AutoTranslator] Level: 1
TheRoom2では下記となりクラス名は'UILabel'であることがわかります。『UILabel Unity』とGoogleで検索した結果からUILabelはNGUIで使用されているクラス名であることがわかります。
[Info :XUnity.AutoTranslator] Setting text on 'UILabel' to '現在のプロファイル'
[Info :XUnity.AutoTranslator] Path : /UI Root (2D)/Camera/Anchor/SelectGamePanel/Anchor Top Right/Current Profile Label
[Info :XUnity.AutoTranslator] Level: -1
クラス名 | テキストフレームワーク |
---|---|
UILabel | NGUI |
TMPro.TextMeshProUGUI | TextMeshPro |
この後はテキストフレームワーク毎の対応となります。なおTextMeshPro、NGUI以外はわからないので本記事では扱えません。(UGUIは前述の通り"OverrideFont="で何とかなるかも??)
5-2. TextMeshPro時の対応
TextMeshProの場合はXUnity.AutoTranslatorの機能で外部ファイルのフォントへ変更することが可能です。この機能はゲームのリソース(Assets)を後からロードするAssetBundleというUnityの仕組みで作られています。そのため、ゲームと外部ファイルのバージョン(UnityとTextMeshProの両方 特にTextMeshProが重要?)が一致していないと正しく読み込めない場合があります。XUnity.AutoTranslatorのリリースページにはTMP_Font_AssetBundles.zipというファイル名で2種類のフォントが公開されています。
圧縮ファイル | ファイル | 用途 |
---|---|---|
TMP_Font_AssetBundles.zip | arialuni_sdf_u2018 | Unity 2018用 |
arialuni_sdf_u2019 | Unity 2019用 |
まずは上記ファイルを試してみます。arialuni_sdf_u2018とarialuni_sdf_u2019がgame.exeと同じフォルダへなるようにTMP_Font_AssetBundles.zipを解凍(または解凍後に移動)してください。
次にどちらのファイルを使用するかUnityのバージョンを確認するためログを開きます。ログには下記のような行があり、この場合(TheRoom4)は 2019.4.5f1 であることがわかります。
Unity 2019であることがわかったのでarialuni_sdf_u2019を使用するよう設定ファイルを下表のように書き換えます。(Unity 2018だった場合は arialuni_sdf_u2018 に読み替えてください)
次にどちらのファイルを使用するかUnityのバージョンを確認するためログを開きます。ログには下記のような行があり、この場合(TheRoom4)は 2019.4.5f1 であることがわかります。
[Info :XUnity.AutoTranslator] Loaded XUnity.AutoTranslator into Unity [2019.4.5f1] game.
設定ファイル:BepInEx\config\AutoTranslatorConfig.ini | |
項目 | 変更理由等 |
---|---|
[Behaviour] OverrideFontTextMeshPro=arialuni_sdf_u2019 FallbackFontTextMeshPro= |
テキスト更新時にフォントを指定されたもので上書きします。FallbackFontTextMeshProの利用が推奨されていますがファイルが利用できるか確認するため必ず上書きされるOverrideFontTextMeshProを使用します。なおFallbackFontTextMeshProは空欄にしてください。両方指定されているとAssetBundleの二重ロードで失敗した場合にFallbackFontTextMeshProのみ指定された時と同様の動きとなるためです。 |
日本語が表示された
arialuni_sdf_u2019が使用できる事が確認できました。これで日本語化(自動翻訳化)完了です。
しかし今はOverrideFontTextMeshProに設定しているのでFallbackFontTextMeshProにだけ指定した場合はどうなるか試してみてください。
特にOverrideFontTextMeshProにだけ指定した時と変化がないようならFallbackFontTextMeshProにだけ指定した状態で使用してください。(FallbackFontTextMeshProの利用が推奨されているため)
文字が消えたり□に戻ってしまう場合はOverrideFontTextMeshProにだけ指定した状態で使用してください。
変わらない(消えたまま/□のまま)
しかし今はOverrideFontTextMeshProに設定しているのでFallbackFontTextMeshProにだけ指定した場合はどうなるか試してみてください。
特にOverrideFontTextMeshProにだけ指定した時と変化がないようならFallbackFontTextMeshProにだけ指定した状態で使用してください。(FallbackFontTextMeshProの利用が推奨されているため)
文字が消えたり□に戻ってしまう場合はOverrideFontTextMeshProにだけ指定した状態で使用してください。
もう一つのファイル(arialuni_sdf_u2018)も同様に試してみてください。
TMP_Font_AssetBundles.zipの2ファイルで日本語表示できない場合はログを確認してください。
もし下行があればファイル配置が異なります。game.exeと同じ場所にarialuni_sdf_u2018とarialuni_sdf_u2019があるか再度確認してください。
[Info :XUnity.AutoTranslator] Attempting to load TextMesh Pro font from internal Resources API.
もし下記2行が続けてある場合はファイル(AssetBundle)のロードには成功したがその中からフォント(TMPro.TMP_FontAsset)を取り出そうとして失敗しています。(TheRoom4と同症状)
[Info :XUnity.AutoTranslator] Attempting to load TextMesh Pro font from asset bundle.
[Error :XUnity.AutoTranslator] Could not find the TextMeshPro font asset: arialuni_sdf_u2019
この場合は自分でファイルを作成すれば日本語表示が可能になるかも知れません。そのためにはゲームが使用しているTextMeshProのバージョンを知る必要があります。
他にもっと良い方法があるかも知れませんが、私はUABEAでゲーム内のフォントを開きデータ構造からバージョンを判断しました。
他にもっと良い方法があるかも知れませんが、私はUABEAでゲーム内のフォントを開きデータ構造からバージョンを判断しました。
試しにTMP_Font_AssetBundles.zip内の2ファイルを調べてみます。
UABEAでarialuni_sdf_u2019を開きます。圧縮されているので展開先を聞かれます。[Memory]を選択します。
その後[Info]をクリックします。開いたAsset Infoウィンドウで"ARIALUNI SDF"(Type=MonoBehaviour)を選択し[View Data]をクリックします。
この時に表示されるデータ構造がどのバージョンのTMPro.TMP_FontAssetであれば辻褄が合うかを調べます。
UABEAでarialuni_sdf_u2019を開きます。圧縮されているので展開先を聞かれます。[Memory]を選択します。
その後[Info]をクリックします。開いたAsset Infoウィンドウで"ARIALUNI SDF"(Type=MonoBehaviour)を選択し[View Data]をクリックします。
この時に表示されるデータ構造がどのバージョンのTMPro.TMP_FontAssetであれば辻褄が合うかを調べます。
arialuni_sdf_u2019はm_Versionが存在することからTextMeshPro v1.4以降ではないかと思われます。
・v1.4以降にはTMP_FontAsset.versionが存在する。
・v1.3以前にはTMP_FontAsset.versionが存在しない。
(Fieldsにも基底クラスのTMP_Assetにも見つからない)
・v1.3以前にはTMP_FontAsset.versionが存在しない。
(Fieldsにも基底クラスのTMP_Assetにも見つからない)
このversionというプロパティはv1.4で追加されてからv3.2まで"1.1.0"で変わらないようです。v1.4~v3.2は バージョンが変わらない=データ構造が変わらない=互換性がある …と思っています(未確認)。
・v3.2までversionは"1.1.0"のまま変化なし。
・v4.0からTMPro.TMP_FontAssetは非推奨??
UnityEngine.TextCore.Text.FontAssetが使用される?
・v3.2までversionは"1.1.0"のまま変化なし。
・v4.0からTMPro.TMP_FontAssetは非推奨??
UnityEngine.TextCore.Text.FontAssetが使用される?
同様にarialuni_sdf_u2018はm_CreationSettingsが存在し、m_Versionが存在しないことからTextMeshPro v1.3ではないかと思われます。
・v1.3以降にはTMP_FontAsset.creationSettingsが存在する。
・v1.2以前にはTMP_FontAsset.creationSettingsが存在しない。
(かわりにTMP_FontAsset.fontCreationSettingsが存在する)
・v1.2以前にはTMP_FontAsset.creationSettingsが存在しない。
(かわりにTMP_FontAsset.fontCreationSettingsが存在する)
次にゲームを調べます。まずは調査すべきデータを探します。TypeがMonoBehaviourでNameが" SDF"で終わっているデータを探し[View Data]で見たとき先頭行が"MonoBehaviour Base (TMP_FontAsset)"となっていればアタリです。
条件にあうデータが複数ある場合はどれでも大丈夫です(データ構造は同じはずです)。そのため、UABEAで開くファイルは"game_Data\resources.assets"で大丈夫だと思いますが、もし見つからない場合は"game_Data\sharedassets0.assets"等のファイルも探してみてください。
条件にあうデータが複数ある場合はどれでも大丈夫です(データ構造は同じはずです)。そのため、UABEAで開くファイルは"game_Data\resources.assets"で大丈夫だと思いますが、もし見つからない場合は"game_Data\sharedassets0.assets"等のファイルも探してみてください。
例としてTheRoom4を調べていきます。
UABEAで"OldSins_Data\resources.assets"を開きます。Asset Infoウィンドウのメニューバーから[View]-[Filter]でType Filterウィンドウを表示。[Deselect all]で全非選択にした後[MonoBehaviour]のみをチェックして[X]で閉じる。いちばん初めのデータが"Anton SDF"と" SDF"で終わっているので[View Data]をクリック。表示されたデータの先頭行が"MonoBehaviour Base (TMP_FontAsset)"となっているのでこのデータの構造を見ていきます。
UABEAで"OldSins_Data\resources.assets"を開きます。Asset Infoウィンドウのメニューバーから[View]-[Filter]でType Filterウィンドウを表示。[Deselect all]で全非選択にした後[MonoBehaviour]のみをチェックして[X]で閉じる。いちばん初めのデータが"Anton SDF"と" SDF"で終わっているので[View Data]をクリック。表示されたデータの先頭行が"MonoBehaviour Base (TMP_FontAsset)"となっているのでこのデータの構造を見ていきます。
このデータ構造にはfontCreationSettingsがありm_CreationSettingsがないことからv1.2以前であることがわかります。さらに詳しく見ていくとm_kerningPair内にAscII_Leftという項目がありますがv1.2のドキュメントには記載がありません。最も古いv1.0.26のドキュメントにも記載はありません。
・v1.2 : AscII_Leftなし
・v1.0.26 : AscII_Leftなし
・v1.0.26 : AscII_Leftなし
仕方がないのでUnityEditorのPackage Managerで下記バージョンのTextMeshProをダウンロードしソース(Library\PackageCache\com.unity.textmeshpro@1.0.2x\Scripts\Runtime\TMPro_FontUtilities.cs)を確認しました。
・v1.0.26 : なし (FormerlySerializedAsの記載あり)
・v1.0.25 : なし (FormerlySerializedAsの記載あり)
・v1.0.23 : あり
・v1.0.21 : あり
・v1.0.26 : なし (FormerlySerializedAsの記載あり)
・v1.0.25 : なし (FormerlySerializedAsの記載あり)
・v1.0.23 : あり
・v1.0.21 : あり
このことからTheRoom4にはv1.0.23以前のTextMeshProが使用されていると思われます。そのためファイル(AssetBundle)にはTextMeshPro v1.0.23で作成したフォントを入れることにします。(FormerlySerializedAsの記載があることからv1.0の間では互換性があると思います。そのためv1.0.26でも良かったかも知れません。)
データ構造とTextMeshProのバージョンについてわかったことをまとめると下表となります。
データ構造 | TextMeshPro |
---|---|
m_Versionがあり"1.1.0"である | v1.4~v3.2 |
m_CreationSettingsがありm_Versionがない | v1.3 |
fontCreationSettingsがありm_CreationSettingsがない | ~v1.2 |
m_kerningPair内にAscII_Leftという項目がある | ~v1.0.23 |
この後はゲームと同じ(もし無ければ近い)バージョンのUnityEditorをインストールしてプロジェクトを作成。そのプロジェクトのPackage ManagerでTextMeshPro(ゲームと同じバージョン)とAssetBundleBrowser(デフォルトのバージョンでOK)をインストール。TextMeshProの"Font Asset Creator"でフォントを作成。"AssetBundle Browser"を起動し出来上がったフォントを入れてBuildすればフォントファイル(AssetBundle)の完成です。
arialuni_sdf_u2019と同じようにファイルを配置・設定ファイルの変更を行い日本語表示できるか確認します。
arialuni_sdf_u2019と同じようにファイルを配置・設定ファイルの変更を行い日本語表示できるか確認します。
この自作したファイルでも日本語表示できない場合、またはゲームを調査してTextMeshProがv1.3~v3.2だった場合(本来arialuni_sdf_u2018/u2019で日本語表示できたはず)はAssetBundleの一部書換が必要かも知れません。UABEAでAssetBundleを開き"TMP_FontAsset"(Type=MonoScript)を表示します。この中のm_AssemblyNameにあるdll(下図では"com.unity.textmeshpro.Runtime.dll")が下記フォルダに存在するか確認します。
種類 | フォルダ |
---|---|
Mono x86 Mono x64 |
game_Data\Managed |
IL2CPP x86 IL2CPP x64 |
BepInEx\unhollowed |
もし無ければここを存在するdllの名前へ変更することで読み込めるようになるかも知れません。
何というファイル名へ書き換えればよいのか確認するため、ゲーム内のAssetsから"TMP_FontAsset"(Type=MonoScript)を探します。TheRoom4では"OldSins_Data\globalgamemanagers.assets"にありましたが必ずどのゲームもこのファイルにあるとは限らないと思います。なかなか見つからない場合はAssetStudioなどフォルダごと読み込める別ツールを使用して探してください。
何というファイル名へ書き換えればよいのか確認するため、ゲーム内のAssetsから"TMP_FontAsset"(Type=MonoScript)を探します。TheRoom4では"OldSins_Data\globalgamemanagers.assets"にありましたが必ずどのゲームもこのファイルにあるとは限らないと思います。なかなか見つからない場合はAssetStudioなどフォルダごと読み込める別ツールを使用して探してください。
上図のとおりゲーム内のTMP_FontAssetではm_AssemblyNameが"TextMeshPro.dll"なのでAssetBundleも同名へ書き換えれば良いことがわかります。
UABEAでAssetBundleを開き"TMP_FontAsset"(Type=MonoScript)を表示する一歩手前まで進み[View Data]ではなく[Edit Data]をクリックします。表示されたEdit Dataウィンドウでm_AssemblyNameを書き換えて[OK]をクリック。Assets Infoウィンドウのメニューから[File]-[Save as...]を選択するともう一つのウィンドウでもセーブするようにメッセージが表示されるので[OK]。Assets Infoウィンドウを閉じて、タイトルが"UABEA"となっているウィンドウでもメニューから[File]-[Save as...]を選択する。新しいファイル名をつけて[OK]をクリックしUABEAを閉じます。この新しいファイルのままでも使用できますが、無圧縮になったため変更前に比べてファイルサイズがかなり大きくなっています。そのためUABEAで圧縮します。UABEAで新しいファイルを開きメニューから[File]-[Compress]を選択。再度新しいファイル名をつけて[OK]をクリックします(この時上書きは不可みたいです)。圧縮方式を聞かれるので[LZMA]をクリック。圧縮が完了したらUABEAを閉じます。必要に応じて圧縮前のファイルを削除したり圧縮後のファイルをリネームします。
UABEAでAssetBundleを開き"TMP_FontAsset"(Type=MonoScript)を表示する一歩手前まで進み[View Data]ではなく[Edit Data]をクリックします。表示されたEdit Dataウィンドウでm_AssemblyNameを書き換えて[OK]をクリック。Assets Infoウィンドウのメニューから[File]-[Save as...]を選択するともう一つのウィンドウでもセーブするようにメッセージが表示されるので[OK]。Assets Infoウィンドウを閉じて、タイトルが"UABEA"となっているウィンドウでもメニューから[File]-[Save as...]を選択する。新しいファイル名をつけて[OK]をクリックしUABEAを閉じます。この新しいファイルのままでも使用できますが、無圧縮になったため変更前に比べてファイルサイズがかなり大きくなっています。そのためUABEAで圧縮します。UABEAで新しいファイルを開きメニューから[File]-[Compress]を選択。再度新しいファイル名をつけて[OK]をクリックします(この時上書きは不可みたいです)。圧縮方式を聞かれるので[LZMA]をクリック。圧縮が完了したらUABEAを閉じます。必要に応じて圧縮前のファイルを削除したり圧縮後のファイルをリネームします。
こうしてm_AssemblyNameを書き換えたファイルで再度日本語表示できるか確認します。
TheRoom4の場合はこれで日本語表示ができましたが、これでも日本語表示ができない場合は…頑張って解析を続けるしかないと思います。
TheRoom4の場合はこれで日本語表示ができましたが、これでも日本語表示ができない場合は…頑張って解析を続けるしかないと思います。
TextMeshPro編の最後にTextMeshProのバージョンとm_AssemblyNameをまとめると下表となります。
名前 | TextMeshPro | m_AssemblyName |
---|---|---|
TheRoom4 | ~v1.0.23 | TextMeshPro.dll |
自作AssetBundle | v1.0.23 | com.unity.textmeshpro.Runtime.dll |
arialuni_sdf_u2018 | v1.3 | Unity.TextMeshPro.dll |
arialuni_sdf_u2019 | v1.4~v3.2 (TMP_FontAsset.version="1.1.0") |
Unity.TextMeshPro.dll |
5-3. NGUI時の対応
NGUIの場合はTextMeshProのようにXUnity.AutoTranslatorの機能でゲーム内のフォントを外部ファイルのフォントで上書きするようなことはできません。そのため、UnityEditor + NGUIで日本語表示可能なフォントを作成しUABEA等でゲーム内のフォントと入れ替える(ゲームのAssetsを書き換える)というのが正攻法だと思います。しかし、単純に入れ替えると言っても整合性を保ちつつ入れ替えなければならないため、ゲームの解析が必要になります。先人たちの情報をもとに頑張れば何とかなる…かもしれませんが大変そうです。
そのため、TheRoom2,3ではXUnity.AutoTranslatorの"XUnity.AutoTranslator.Plugin.Core.dll"に下記コードをdnSpyで追加することで日本語表示可能なフォントへ入れ替えました。
// XUnity.AutoTranslator.Plugin.Core.AutoTranslationPlugin.SetText
namespace XUnity.AutoTranslator.Plugin.Core
{
…省略…
public class AutoTranslationPlugin :
…省略…
{
…省略…
private void SetText( object ui, string text, bool isTranslated, string originalText, TextTranslationInfo info )
{
…省略…
#ifdef _THE_ROOM_TWO_PATCH_
if (ui.GetType() == typeof(UILabel)) {
UILabel label = (UILabel)ui;
if (isTranslated) {
if (label.font.replacement == null) {
UIFont font2 = null;
foreach ( var f in Resources.FindObjectsOfTypeAll() )
{
if ((label.font.name + "2") == f.name) {
font2 = f;
break;
}
}
if (font2 == null)
{
var fonts = Resources.FindObjectsOfTypeAll();
font2 = Instantiate(label.font);
font2.name = label.font.name + "2";
font2.material = null;
font2.dynamicFont = fonts[0]; // Arial
XuaLogger.AutoTranslator.Info(string.Format("made UIFont {0}({1})", font2.name, font2.GetInstanceID() ));
}
else
{
XuaLogger.AutoTranslator.Info(string.Format("found UIFont {0}({1})", font2.name, font2.GetInstanceID() ));
}
label.font.replacement = font2;
}
}
else
{
label.font.replacement = null;
}
}
#endif
ui.SetText( text, info );
…省略…
}
…省略…
}
}
NGUIのフォントであるUIFontにはdynamicFontというプロパティがあり、これにFontを入れればダイナミックフォントになってくれるようです。TheRoom2,3ではゲームのリソース内にFontがArialしかありませんでしたが、これを入れてみたところOSフォントで代替してくれたようで(見た目はあまり美しくありませんが)日本語表示が可能でした。その後、[Alt]+[T]で原文⇔訳文を切り替えたときにフォントも切り替わるようにしたのが上記コードとなります。
TheRoom2,3以外でもNGUIを使用しているゲームならこのコードが使えるかも知れませんが、かなり決め打ちでコードを書いているので他ゲームだとそのままでは使用できないかも知れません。
私が現在気づいている懸念点は下記のとおりです。
- ゲーム内でUILabel.font.replacementを使用していないことを前提にしている。
使用しているゲームだとフォント(表示)がおかしくなる
- ゲーム内に名前が"2"で終わるUIFontがないことを前提にしている。
nameとname2という後ろに"2"が付いた名前のUIFontと付いていない名前のUIFontがもともとゲーム内に存在していた場合、name2をnameの日本語表示用UIFontとして誤認する。
- ゲーム内のリソースにFontが最低1つは存在していることを前提にしている。
もし無ければ例外発生。日本語表示用UIFontも作成できない。
- ゲーム内(Assembly-CSharp.dll)で定義されているUILabel,UIFontを普通に使っている。
NGUIを使用しているなら、そのゲームのAssembly-CSharp.dllにもUILabel,UIFontがあるはず。しかし、バージョンの違いにより存在しないプロパティなどがあった場合はコンパイルが通らない。
使用する場合はこの辺りにお気を付けください。
なお、TheRoom2用にインストールした"XUnity.AutoTranslator.Plugin.Core.dll"へ上記コードを追加する手順は下記のとおりです。
- dnSpyを起動します。既に何か読み込んでいた場合、[File]-[Close All]でAssembly Explorer(左のツリー)を空にします。
- [File]-[Open]で BepInEx\plugins\XUnity.AutoTranslator\XUnity.AutoTranslator.Plugin.Core.dll を開きます。
- [Edit]-[Search Assemblies]でフォーカスが移ったところに XUnity.AutoTranslator.Plugin.Core.AutoTranslationPlugin.SetText を入力し[enter]キーを押します。
- 入力欄の下に表示された SetText をダブルクリックし、AutoTranslationPluginクラスのメソッド SetText へジャンプします。
- SetTextメソッド内でマウスを右クリック。表示されたメニューの[Edit Method (C#)...]を選択。コード編集画面が開きます。
- 上記コードの#ifdef~#endifの間を#から始まる行を含めずにコピー、SetTextメソッド内のui.SetTextの前へペーストします。
- コード編集画面左下にある[Add Assembly Reference]ボタン(ファイルを開くアイコン)を押し下記ファイルを選択します。(ボタンを押してファイルを選択する…を繰り返します)
BepInEx\core\XUnity.Common.dll TheRoomTwo_Data\Managed\UnityEngine.dll TheRoomTwo_Data\Managed\Assembly-CSharp.dll
- コード編集画面右下にある[Compile]を押します。コンパイル後コード編集画面が閉じられます。([Compile]でコード編集画面が閉じないのであれば何らかのエラーが発生しているはずです。問題を解決してコンパイルが通るようにしてください。)
- [File]-[Save Module...]でダイアログを開き、デフォルトのまま[OK]を押します。その後[File]-[Exit]でdnSpyを閉じます。