以前にアプリサイズを減らす方法を出したが、もう少し減らせる方法を思いついた。
決してFacebookで紹介されて嬉しかったからではない。
[Unity3D]iosアプリサイズを節約する
http://tsubakit1.hateblo.jp/entry/20120512/1336773155
ただし今回紹介する方法は、実にUnity的ではない。そのため色々と正規の手順と比較して面倒な箇所が多いと思うが、その辺りは注意してほしい。あと事故っても泣かない事。
ちなみにUnity4で検証。Unity3系はもう使わないと思う。
■テクスチャを小さくする
まず最初のステップ、画像自体を小さくする。そのために「TinyPNG」のサービスを利用する。無料で使用出来る画像縮小のWebサービスで、PNGの画像を画質をほとんど変化させず最大85%近く小さくすることのできる。
TinyPNG
http://tinypng.org/
下の画像は、どちらかがオリジナル・どちらかが変換を掛けた画像だ。見た目はそれほど変わらないが、オリジナルのサイズは282kb、圧縮後の画像は105kbと大分違う。ちなみにPVRTCで圧縮した場合は700kb前後になる。RGBA32は5MBくらい。
ただし、このまま画像をインポートしてもUnityは勝手に「ゲーム実行に適したフォーマット」に変換してしまう。iOSであればPVRTC、AndroidであればDAXやPVRTC、もしくはRGBA16等だ。
これでは圧縮した意味が無い。
■StreamingAssetsに置きWWWで参照
そこで、変換せずにファイルを保持する。以前紹介したStreamingAssetsにファイルを入れることで、ファイルは変換されずにそのままアプリに含むことが出来る。
そして参照するにはWWWを使い非同期でロードする。勿論I/Oでも良いが、画面が一瞬固まってしまうので非同期で呼び出せるWWWを使ったほうが幸せな人が多いかもしれない(日本のゲーム的には)。
[Unity3D] StreamingAssetsについて
http://tsubakit1.hateblo.jp/entry/20120917/1347807947
[Unity3D]UnityBasicでもテクスチャを非同期でロードする
http://tsubakit1.hateblo.jp/entry/20130117/1358431354
ちなみに、この方法で作成する画像はPNGからそのまま生成するためRGBA32と同じくらい綺麗に表示できる。そして、iOS Basic、Android Basicでも動作する。例えばカードゲームのカードやキャラクターの立ち絵・CGはこういった方法で取得する方法も悪くないかもしれない。
一応想定の使い方は、NGUIのAtlasに登録したマテリアルのテクスチャを更新する感じ。
■リスクのない方法は無い(持論)
さて、この便利な方法だが、いくつか問題がある。
まず一つ目の問題は「StreamingAssets」に物を大量に置くとUnity自体の起動時間が非常に伸びることだ。理由は多分Resourcesと似たような理由だと予想しているが(Resourcesも物を大量に置くと起動が遅くなるらしい)、実際はどうなのかは分からない。Unity4.0.1ではこういった事は発生しない模様。
さらに、StreamingAssetsに置いたものは「外から丸見えになる」といった問題もある。Resourcesのように一手間かけるまでもなくファイルが丸見えになるため、管理には一工夫が必要になる。
まだある。メモリ関連の問題だ。実はこの方法は通常の方法よりメモリを食う。WWWはとっとと破棄してるから大したことにはならないハズだが、その過程でWWW+Textureのメモリを消費する。また、Texture自体もcompressで多少消費メモリが減るとはいえ、完璧に減るわけではない。(ちなみに圧縮するためには画像はPOTを推奨)
さらに、非同期処理が追加されることで管理が少し複雑になる。これは理解しているなら簡単に何とか出来るし、マルチスレッドな状況と比べたら非常に簡単だが、「使えるから使おう」と思って使うと火傷になるかもしれない。
最後に、この方法は2Dゲーム向けな気がする ←(今更