技術と趣味の亜空間

主にゲームプログラミングとその周辺に関する記事を不定期で上げていきます

TextMeshProをAddressablesに対応させる

TextMesh Pro Title

概要

TextMeshProのフォントデータやシェーダといったリソース関係は "Essential Resources" としてローカルフォルダに設置しますが、このフォルダがResourcesフォルダであるため、Addressable 化するには Resources フォルダから外してやる必要があります。
しかし外すとUnity起動時やゲーム実行時など、事あるごとに「Import Essential Resources」の初期設定ポップアップが表示され、まともに開発できなくなります。
TextMeshPro を使っているシーンやプレハブを Addressable にした場合は、 TextMeshPro も一緒に Addressable に対応しないと、依存関係の問題でフォントデータなどが二重でメモリに読み込まれることになります。特に日本語フォントデータは大体16~32MBくらいになると思うので、それが2倍になると考えるとプロダクトでは大きな課題となります。

今回はこの問題を解決する記事となります。

執筆時環境:

  • Unity 2021.3.3f1
  • TextMeshPro 3.0.6
  • Addressables 1.21.2

解説

「Import Essential Resources」の初期設定ポップアップが毎回表示される原因は、TMP Settings.assetという設定ファイルが Reousrces フォルダに設置されているかどうかをTextMesh Proのライブラリ側でチェックしているのが原因です。
なので、その読み込みコードをAddressables版に差し替えれば解決します……が、ライブラリ側であるため、修正するにはコードを PackageManager からローカルプロジェクトにまるっと移さないといけません。
この方法だとライブラリ更新時の修正・管理が面倒というのと、いずれ公式が Addressables について何からの対策をすると思うので*1、それまでの暫定対処として今回はライブラリを弄らずに Addressable に対応させます。

コード

Githubにサンプルプロジェクトとunitypackageを用意しました。
AddressableデータもWindowsだけですがビルドしてありますので、すぐに表示を確認することが出来ます。
インポート後、AddressableTextMeshProFixer.cs内のTMP SettingsDefault Font Assetのアドレスを各自で設定したものに修正してください。

github.com

内部仕様

リフレクションを活用して実行時やエディタの起動時、アセット変更時などでTMP Settingの参照周りをハックしています。
これにより、TMP Settings.assetをResourcesフォルダから外しても「Import Essential Resources」の初期設定ポップアップが出なくなります。
しかし、これだけではまだ読み込み時にフォントデータが2重でメモリに積まれる問題が残っており、その原因はTMP SettingsのDefault Font Assetsにフォントデータがセットされているため。
その対策として、Default Font Assetsをビルド中だけ一時的に空にする処理のコードも用意しています。こちらはEditorフォルダ内に追加します。
これで晴れてEssential ResourcesをAddressablesにさせることができます。

*1:2020年時点ではAddressablesを直接サポートする予定は無いらしく、将来的にはユーザーがTMP Resourcesの読み込み先を自由カスタマイズできるようにする模様。ただし、その機能は自分が調べた限りpreview3.2.0 ~ 4.0.0でもまだ追加はされていないように見える。