TextMeshProをAddressablesに対応させる
概要
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 Settings
とDefault Font Asset
のアドレスを各自で設定したものに修正してください。
内部仕様
リフレクションを活用して実行時やエディタの起動時、アセット変更時などで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でもまだ追加はされていないように見える。