Dinamic Font を前提にしたアウトラインデータ Font を対象に話ます。
#まず最初に
Font にはライセンスがあります。
PC に入ってるからと言って、勝手にアプリに使ってはいけない場合があります。
業務でアプリを作っている方(個人でも!)は特に意識しましょう。
デザイナーさんから、プランナーさんから渡されたから使用してるって方は、ライセンスはクリアしてる?
ってのを意識してみましょう。
Font データを扱う投稿なので、意識高い系を装って前文を書いてみました(笑)
#今回は Free Font を個人で実験
商業 Font をライセンス(アプリ埋め込み&配布可能)購入していても、AssetBundle で DownLoad 可能にするのは
そもそも認められていない可能性が高いので、お仕事で実行に移したい!って方は確認をお勧めします。
#経緯
日英中韓などの言語(UI含む)切り替え設定ありアプリを開発するには?
ってのが始まりです。
日本語 Font ならアスキーは入ってるでしょうから日英はクリアー出来たとしても
繁体字、簡体字やハングルなどは別データとなっていて容量も大きいのがネックです。
さらに仕事だと、知らぬ間に上層部やPやDなどは世界主要言語をカバー!
とか言い出す処か、決定してたりします(笑、、えるのか?)
じゃ、設定切り替えたら DownLoad するようにすれば?から始まりました。
で色々と調べてみると、AssetBundle の Variant を使って Text(string)データが違うリソースを切り替える方法
とかヒットするんですが、どこにも Font リソース自体をアプリ外だしって内容が見つからないんです。
#結論
最初に言ってしまえば、力業で実験は成功しましたが、スマートでは無いし、
商業規模のプロジェクトで作業化するには厳しい内容だと言わざるを得ませんでした。
なにより Unity の動作的に保障されるのか?ってのもあります。
#やり方
UnityEditor作業
1)
まず Asset Bundle Manager を利用して、Local Asset Bundle サーバーで実験しました。
(シミュレートはオフ)
普通に Unity に Font をインポートさせて、Scene でも Prefab でも UI.Text でデータを作ります。
インポートしている Font リソースを AssetBundle 化します。
そしておもむろに Projectインスペクタより Font リソースを Deleta します。
当然 UI.Text の Font メンバは Missing になります。しかし text 内容やアライメント設定や位置情報は残っています。
アプリ実行中処理
1)
アプリで AssetBundle 化した Font を DownLoad します。
型としては UnityEngine.Font になると思います。
Scene でも Prefab でも UI.Text が必要なタイミングで UI.Text を取得します。
今回は FindObjectsOfType で UI.Text[] を取得しました。
インスタンス化した UI.Text.font メンバは Missing どころか None になっています、、
そしておもむろに UI.Text.font メンバに DownLoad した UnityEngine.Font class を代入します。
以上!
#問題点
いろいろと突っ込み処満載ですが、、、
まず、Font リソースを Delete してる時点で meta ファイル(GUID)も消えてしまうので
Unity さんに Missing 状態を回復するヒントすら残せません。
さらに UnityEditor で手動で削除って(笑)
これは CL Build する際に指定する static メソッド内に AssetDatabase.Delete とか記述とかしないとなんですが
実験なんで、その辺の業務に耐える手法的な部分はご容赦を。
そして極め付けは、UI.Text.font メンバに代入する!!!
- 1:Font が複数種類あったらどうするの?
- 2:Scene とか Prefab なんて色んなタイミングでインスタンス化するんですけど?
- 3:おいおい UI.Text.text データは残るって言うけど、Font 変えたんだから string 情報も変えないとだろ?
はい、ご容赦出来ない業務で実用に耐えるようにするにはクリアしないとダメな内容が盛りだくさんです。
まず1から
これは UI.Text の name に判別できる名目規則をつけるとか FontSize とかで一律決めの Font にする
とかのルール&適応処理を作るしか思いつきません。
次に2
これも Scene をロードしたら & Prefab をインスタンス化したら
それらを対象にした全ての UI.Text を何らかしらの手段で取得する仕組みを実装する位しか思いつきません。
(嫌われものの FindObjectsOfType も初回一回だけならアリかと)
3ですがこれは意外に解決できそうです。
サーバ側かアプリローカル(YAMLとか)に対応する文字列を用意して、言語設定により使用する string 情報を変更する処理
前提で UI や画面をレイアウト込(文字数変わる前提)で作れば良いのです。
、、ん?それが超大変ですと!?
いやいやいや、複数言語対応をしたいのはご自身でしょ? 別に Unity が機能をうたって売りにしてる訳じゃないのです!
そのくらいはクリアして実装しないと実現出来ませんよ。
、、でも文字数変わるとけど同一レイアウトって実は超ムズです。
世の中的には国が変わると UI(そもそもアプリ) 変えるって手法なのが理解できた実験でした。