(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

Unityで作ったアプリのサイズを減らす20の方法【Unity】【容量削減】


このエントリーをはてなブックマークに追加

この記事はUnity Advent Calendar 2018の5日目の記事です。


この記事でのバージョン
Unity 2018.2.2f1


はじめに

Unityは画像や音源をそのまま使っているわけでないので、

PC上のアセット(ファイル)のサイズとアプリに含まれるアセットのサイズが異なっていたり

プロジェクトに入ってるアセット= アプリに含まれる(ビルドされる)アセットではないので、

使っていないアセットがアプリに含まれてしまったりと、ちょっと特殊な感じで、

最初のうちは完成したアプリのサイズを減らそうと思ってもなかなか上手くいきません。


という事で今回は「Unityで作ったアプリのサイズを減らす方法」を知っているかぎりまとめてみました!


なお、Unityのバージョンやデータの内容、プラットフォーム違い等で結果は変わるかもしれないので、

実際に確かめながら削減する事をオススメします。


また、本記事に出てくるアセットは以下のものを使っています。







ビルド時の圧縮設定

アプリのサイズを減らす上で簡単かつ効果的なのが、

ビルド時の圧縮設定であるCompression Methodを見直すことです。


f:id:kan_kikuchi:20181204173948j:plain


ここは最初Defaultになってるのですが、他の設定に変えるだけでアプリのサイズが減ります。

試しにDefaultでビルドすると123.8MBだったアプリを

LZ4したら92.4MB、LZ4HCにしたら88.7MBに減りました。


ただし、圧縮するほどロードは遅くなるので、プロジェクトに合わせて慎重に決めましょう。


なお、後述するAssetBundleを使ってる場合は効果が薄いです。


不要なアセットが含まれないようにする

当たり前ですが、使っていないアセットがアプリに入ってるのは無駄です。

しかし、前述の通りUnityはアセットの扱いが特殊なので、

どのアセットがアプリに入ってるか調べるのは結構面倒だったりします。


そんな時に使えるのが、ビルド時のログです。

なお、ビルド時のログはConsoleの右上にあるメニューにある、Open Editor Logから見る事が出来ます。


f:id:kan_kikuchi:20181204132449j:plain


ビルド後にログを確認すると、Build Reportという項目が表示されていて、

アプリに含まれたアセットの中で種類別に累計サイズが見れたり、重い順にアセットが見れたりします。


f:id:kan_kikuchi:20181204132722j:plain


この中に使ってないアセットがあれば削除すれば良いと言った感じです。


余談ですが、Build Reportをより見やすくするBuild Report Toolなるアセットもあります。




さて、話を戻して次の項からどんな場合にアセットがアプリに入ってしまうかを紹介します。


Resourcesに入っているアセット

Resourcesというフォルダに入れてるアセットは基本的に全てアプリに入ります。

(エクセルなどのUnityで扱えない拡張子のアセットは例外)


f:id:kan_kikuchi:20181204151042j:plain



なので、Resourcesに入れるアセットは絶対にロードするやつだけにしましょう。

例えばシーンに最初から置いて使うアセット等は、別のフォルダに置いていた方が無難です。


また、「使っていないと思ってResourcesから消したら、実はプログラムでロードしててバグになった」

なんて事もあるので、パスは手動で設定せず、自動で設定出来るようにしておくと便利です。



ちなみにResourcesは公式に「Resourcesフォルダのベストプラクティスは使用しない事である」

なんて言われるぐらい推奨されていなかったりします。





Prefabで使われているアセット

ResourcesにPrefabが入ってる場合、そのPrefabで使っているアセットもアプリに含まれます。


以下の例だと、Resourcesに入っているCharacterにcharacter_6という画像が使われているため、

character_6がResourcesに入っていないのに、アプリに入ってしまいます。


f:id:kan_kikuchi:20181204155111j:plain


なので使わなくなったPrefabは、

ちゃんと削除するか、Resourcesから退避するようにしましょう。


Sceneに配置されているアセット

ビルドに含まれているSceneに配置されている物も、アプリに含まれます。


以下の例だと、ビルドに含まれているSampleSceneというSceneに


f:id:kan_kikuchi:20181204151719j:plain


配置されているCharacterというオブジェクトにcharacter_6という画像が使われているため、

character_6がResourcesに入っていないのに、アプリに入ってしまいます。


f:id:kan_kikuchi:20181204151739j:plain


「Sceneに配置されてるけどずっと非表示で実は使ってない画像」や

「ビルドに含まれてるけど実は使ってないScene(に配置されている画像)」などの

「途中までは使ってたけど、最終的に使わなくなった」

みたい感じで意外と残ってしまう事があるので注意が必要です。


StreamingAssetsに入っているアセット

StreamingAssetsという名前のフォルダに入れてるアセットも全てアプリに入ります。

しかもResourcesとは違い、エクセルなどのUnityで扱えない拡張子のアセットも例外ではありません。

(逆にPrefabを入れても、それに使われているアセットが入るという事はない)


f:id:kan_kikuchi:20181204160954j:plain


なお、StreamingAssetsは基本的に使わないので、そんなに気にする必要はないかもしれません。

(後述するAssetBundleをローカルで使いたい場合には使う)


アセットのサイズを減らす

先程紹介したBuild Reportに表示されるサイズはアプリに含まれたアセットのサイズなので、

使っている物であっても、明らかに重すぎるという場合は改善の余地があるということにもなります。


例えばcharacter_6.pngという画像は

PC上では624KBですが、アプリに含まれた後は3.4MBと約5倍になってしまっています。


f:id:kan_kikuchi:20181204133753j:plain
f:id:kan_kikuchi:20181204133742j:plain


という事でここからは、各アセットのサイズの減らし方です。


画像

まずはUIや2Dキャラクター、3Dモデルのテクスチャやエフェクトなど利用用途が多岐に渡り、

アプリのサイズが肥大化するだいたいの原因である画像の話です。

最大サイズ

Max Sizeで最大サイズを設定することが出来ます。


f:id:kan_kikuchi:20181205052929j:plain


例えば元が879✕1000の画像のMax Sizeを512にすれば、450✕512に縮小(比率はそのまま)され、

サイズも3.4MBから0.9MBまで減ります。

なお、"最大"なのでMax Sizeを大きくしても拡大されることはありません。

f:id:kan_kikuchi:20181205053021j:plain


もちろん小さくしたらその分、劣化はするので見栄えとのトレードオフになります。


なお、あくまでUnity上のサイズなので元の画像のサイズは変わりませんし、

既にシーンに配置した画像やPrefabなどの大きさが変わる事もないので、

とりあえず小さくしてみて、劣化が許容出来るか確認する感じになると思います。


圧縮形式

Compressionで圧縮形式を設定することが出来ます。


f:id:kan_kikuchi:20181205055851j:plain


圧縮すればサイズはかなり減るので、基本的には圧縮するようにしましょう。

(ただし、圧縮すると画像が劣化し、ロード時間は増し、メモリの使用量も増える。)

例えばNoneからLow Qualityに設定すると、3.4MBの画像が0.8MBになりました。

なお、サイズの表記は圧縮形式を変えた瞬間に変わるわけではなく、ビルドした時に変わります。


f:id:kan_kikuchi:20181205055904j:plain


圧縮形式はLow、Normal、Highの3つ。

圧縮後のサイズはHighよりLowの方が小さくなりますが、その分画像は劣化します。

(プラットフォームによっては効果が変わらない事もある)


さらに、Use crunch compressionを有効にするとCrunch圧縮を使い、

さらにサイズを減らす事も出来ます。(使えない = 効果がないプラットフォームもある)


f:id:kan_kikuchi:20181205061544j:plain


例えば先程と同じ画像のUse crunch compressionを有効にし、

Compressor Qualityを50にすると101.1KB、10にすると68.4KBになりました。


f:id:kan_kikuchi:20181205061933j:plain
f:id:kan_kikuchi:20181205061941j:plain


これも小さくなるほど、画像は劣化します。


なお、画像のサイズが4の倍数でない場合は圧縮は出来ないので、4の倍数になるように調整しましょう。

Only textures with width/height being multiple of 4 can be compressed to DXT5 format

f:id:kan_kikuchi:20181205062436j:plain


Mip Map

Generate Mip Mapsを無効にする事で

Mip Mapを生成しないようにし、サイズを削減することが出来ます。


f:id:kan_kikuchi:20181205063209j:plain


例えば全画像でMip Mapを生成してビルドすると58.7MBだったものを

Mip Mapを生成せずにビルドすると57.8MBになりました。


ちなみにMip Mapとは小さな画像の事であり、

3Dモデルが遠くにいる時に自動で使われます。(負荷を下げるため)

なので、UIや2Dキャラクターの画像には必要ありません。


画像をまとめる

複数の画像を一つにまとめ、空白を減らすとサイズを減らす事が出来ます。


例えばバラバラの2枚の画像でビルドすると57.8MBだったものを

1枚の画像にまとめてビルドすると55.6MBになりました。


これには処理の負荷を下げる効果もあるので、よほど大きな画像でない限りまとめましょう。


なお、UnityにはSpriteAtlasという画像をまとめるための機能があります。





ベイクの質を下げる

3Dのゲームを作る際にベイク(影を焼いて固定化)するのが一般的ですが、



このベイクの質を下げて、生成される画像のサイズや枚数を減らす事も容量削減には有効です。


なお、ベイクの質はLightmapの設定で変更できます。

また、下部で生成された画像の枚数やサイズを確認する事も可能です。


f:id:kan_kikuchi:20181205111358j:plain


もちろん質を下げれば見栄えが悪くなるので、見栄えと容量のバランスを探るという感じになります。


音源

次は元のファイルが重くなりやすいが、Unity上での改善が比較的難しい音源の話です。

圧縮形式

Compression Formatで圧縮形式を設定することが出来ます。

また、下部に元のサイズ、アプリに含まれた時のサイズ、その倍率を確認することも出来ます。


f:id:kan_kikuchi:20181205071903j:plain


なお、各圧縮形式の概要は以下の通りです。

  • PCM : 品質は高いが、サイズが大きい、短いSE用。
  • Vorbis : 品質は若干低いが、サイズは小さく、圧縮率を調整する事も可能。長いSEやBGM用。
  • ADPCM : サイズがちょっと大きい(PCMよりは小さい)が、CPU使用量が格段に少ない。ノイズを多く含んでいて大量に再生されるSE用。


例えばPCMでビルドすると72.6MBだったもの(BGM2曲入り)を

VorbisのQualityを50にすると56.3MB、Qualityを10にすると56.2MBになりました。


3Dモデル

今度はアニメーションとメッシュ(ポリゴン)、テクスチャ(画像)という

アプリのサイズを減らす上で複合的な要素を持つ3Dモデルの話。

なお、テクスチャについて画像の項目と同じなので省略します。


アニメーションの圧縮形式

Anim. Compressionでアニメーションの圧縮形式を設定することが出来ます。

また、圧縮形式をOff以外にした場合、その下の欄で各数値の許容度合いを設定出来ます。

許容度合いが高いほどサイズは減りますが、アニメーションの質は下がります。

f:id:kan_kikuchi:20181205085607j:plain


例えば全アニメーションのAnim. Compressionがoffでビルドした時に73MBだったものを、

Keyframe Reductionに変更してビルドすると65.2MB、Optimalに変更してビルドすると64.1MBでした。

(どちらも許容度合いは全て0.5)

また、Optimalで各許容度合いを0.9にしてビルドすると64MBでした。


圧縮形式がOffだとかなりサイズが増えるので、基本的に圧縮をした方が良いですが、

許容度合いを高くし過ぎるとアニメの質が下がるので、ここは要相談といった感じです。


ちなみにKeyframe ReductionとOptimalの違いは、

OptimalがGenericでしか使えないという事しか分かりませんでしたが、

Optimalのほうがサイズが小さくなるっぽいです。


メッシュの圧縮形式

Mesh Compressionでメッシュの圧縮形式を設定することが出来ます。

形式はOff、Low、 Medium、 Highの4段階で、

後になるほどサイズは減りますが、より劣化するようになります。

f:id:kan_kikuchi:20181205091313j:plain


例えばMesh Compressionがoffでビルドした時に64MBだったもの(3Dモデルは1体)を、

Lowに変更してビルドすると63.7MB、Highに変更してビルドすると63.6MBでした。


3Dモデル1体だとそこまで変わらない気もしますが、基本的に圧縮をした方が良いと思います。


メッシュのポリゴン削減

あまりにポリゴンが多すぎて重い場合は、削減しても良いかもしれません。

なお、Unity上で簡単にポリゴンを削減出来るアセットもあります。





フォント

最後に日本語対応すると途端に重くなるフォントの話。

なお、Unity上で何かするというわけではなく、フォント自体をどうにかする方法です。

必要な文字だけ取り出す

使用される文字が限られている場合は、

必要な文字だけ取り出して使うとかなりサイズを減らす事が出来ます。



特に漢字を使わない場合は効果的です。


画像にする

使用される文が決まっている場合は、テキストを使わずにいっそ画像にしてしまうのも手です。

ただし、変更が面倒になりますし、画像が増えていくと逆にサイズが増えてしまうので注意が必要です。


設計の見直し

ここからは根本的にプロジェクトの設計を見直しを図り、アプリのサイズを減らそうという話。

当然、作り直す箇所が出てくるのでアセット自体のサイズを減らすより大変になります。


AssetBundleを使う

以前、記事にもしましたが、AssetBundleを使うとアプリのサイズをかなり減らす事が出来ます。

もちろん生成したAssetBundleをサーバに置いてダウンロードして使うようにすれば、

元のアプリのサイズを限界まで小さくすることも可能です。




ただし、AssetBundleを使うのはなかなか難易度が高いですし、開発途中で移行するのは結構面倒です。

また、ローカルでAssetBundleを使うときにはStreamingAssetsというフォルダを使うのですが、

StreamingAssetsに入っているアセットはBuild Reportに表示されなくなります。

(どのアセットが重いのか探しにくくなる。なお、Build Report Toolなら表示出来る)


さらに設計がまずいとアセットが重複してしまい、サイズが余計に増えてしまう場合もあります。

とは言え、Asset Bundle Browserを使えば重複は簡単に見つけられます。



なお、新機能のAddressable Assetsでも同様の効果が期待出来ます。




ScriptableObjectをJSONにする

Unityでは静的なデータを使う時にScriptableObjectを使うと便利ですが、

これを圧縮したJSONにすると、ある程度サイズを減らす事が出来ます。


ただし、ロード時間やメモリ使用量はScriptableObjectの方が優れているので、

本当に限界までサイズを減らしたい!という時の話になると思います。


詳しくは以下の記事を参照のこと。





デフォルトでビルドされないDLLの使用を避ける

Unityではmscorlib.dllやUnityEngine.dllなどのDLLがデフォルトでビルドされるようになっていますが、

System.dllやSystem.Xml.dllなどはコードを使っていなければビルドされません


試しにSystem.Xmlを使ったコードを書いてみた所、

元々55.5MBだったアプリが、55.7MBに増えました。

(usingしただけで実際にコードで使ってない場合は増ない)

//特に意味はない
System.Xml.Xsl.XsltArgumentList xslt;


なので、デフォルトでビルドされないDLLの使用を避ければ、多少サイズ軽減になります。


Net 2.0 サブセットを使う

Player SettingsにあるApi Compatibility Levelを

.Net 2.0から.Net 2.0 Subsetにすると2.4MBほどのサイズ削減が出来ます。


f:id:kan_kikuchi:20181205120503j:plain
f:id:kan_kikuchi:20181205120003j:plain


ただし、Subsetの方は言語的に制限される機能もあるので、注意が必要です。


不要なパッケージを削除する

Unity2018から、TextMesh ProなどのパッケージをPackageManagerで管理出来るようになりました。



このPackageManagerはデフォルトでいくつかのパッケージがインストールされている状態なので、

これを消せばアプリサイズの削減が図れます。(もちろんその機能は使えなくなる)


f:id:kan_kikuchi:20181205120848j:plain


試しに消せるパッケージを全て消した所、0.4MBほど減りました。


Unityのバージョンを変える

Unityはデフォルトの何もない状態でビルドしてもアプリが結構なサイズになりますが、

バージョンによって多少サイズにバラツキがあったりします。


なので、よりサイズが小さいバージョンを使うというのも一つの手かもしれません。

とは言うものの、面倒なのに効果は少ないのでオススメしません。


ちなみにいくつかのバージョンで、空のプロジェクトをMac向けにビルドした際のサイズは以下の通り。

なお、2019はまだ正規版じゃないので、異常にサイズが多くなってるとのだと思われます。

バージョン 容量[MB]
2017.4.16f1 51
2018.2.17f1 55.9
2019.1.0a10 123.9



Tiny Unityを使う

名前の通り、Tiny Unityとは超軽量版のUnityの事で、

コアサイズがたったの72KBないらしく、小さなゲームを作るのに適したUnityです。



ただし、現状はプレビュー版しかありませんし、

言語はTypeScriptしか使えません。(C#のサポート予定はあるみたい)


おわりに

色々とアプリのサイズを減らす手段を紹介しましたが、

どの項目も基本的に何かしらとトレードオフになるので、

許容出来る範囲を模索して、サイズを減らして行く必要があります。


なお、「他にもこんな方法でサイズが減らせるよ!」

という事がありましたら、教えていただけると幸いです!


参考