テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

アプリサイズを減らす 2

以前にアプリサイズを減らす方法を出したが、もう少し減らせる方法を思いついた。
決して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くらい。
スクリーンショット 2013-01-20 23.27.21

ただし、このまま画像をインポートしても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ゲーム向けな気がする ←(今更