Unity:Android向けのビルドまたは「サイズが重要」

場合によっては、 Androidのアセンブリサイズを小さくする必要があります。 たとえば、モバイルインターネットユーザー向けのヘビーウェイトAPKのインストールには、かなりの費用がかかります。 Google Playで50 MBのAPKのサイズを超えると、アップグレード中に追加の問題が発生します。







UnityAndroid向けの2Dゲームを開発しました。これは、写真(ほとんどが透明部分)とさまざまな音でいっぱいで、APKのサイズの問題に直面しています。 将来的には、それを解決し、重量を1.5倍減らすと、ダウンロードが1.5倍増えたと言います。 考えさせられますよね?



重いアプリケーションの問題を克服しようとして、Unityのすばらしいドキュメントに目を向けました。 そこでは、このトピックはついつい議論するだけであることが判明しました。 アセンブリのサイズに影響を与える側面と、APKを小さくするためにこれらの側面に影響を与える方法、および画像のインポートの設定に関するわずかな具体性について正確に言及しました。



この問題に関するその他の有用な情報は、インターネット上ではほとんど見つかりませんでした。 そのため、小規模な調査を実施し、その結果を急いで共有しました。



そのため、ドキュメントによると、 アセンブリサイズは次の影響を受けます。

  1. アセットサイズ(画像と音声);
  2. メッシュとアニメーションクリップ。
  3. 含まれているdllのサイズ。


メッシュとインポートされたアニメーションクリップは使用しなかったため、アセットから始めます。





画像



画像について明確にします。 私たちのゲームでは、 ピクセル完璧の原則が尊重されています。 アルファチャネルのないすべての画像には滑らかなグラデーションがあります。 残りの画像は透明で、不透明な領域にも滑らかなグラデーションがあります。



PNGおよびJPG画像がARCのサイズにどのように寄与するかを分析しましょう。



PNG画像



PNGの場合、この寄与は2つの「変数」に依存します。

  1. ファイルシステム上のイメージのサイズ。
  2. インポート設定。


Photoshopで次の設定で3つの画像を保存しました: 圧縮->最小/低速、インターレースなし:いいえ 295KBのPNG画像は、アセンブリ内で236KBのスペースを占めました。 写真612キロバイトは480キロバイトかかりました。 21.2 KBのイメージには23 KBが必要でした(もちろん、同じインポート設定で)。 命題は明らかです。



次に、Photoshopの最初の画像を設定で保存しました: 圧縮->なし/高速、インターレース:はい 。 サイズが9000 Kバイトのファイルを取得しましたが、同じ236 Kバイトをアセンブリに追加しました。



これにより、 Unityがすべてのアセットを内部形式にトランスコードするというドキュメントの言葉が確認されます 。 明らかに、それはおおよそPhotoshopで保存されたPNGフォーマットに対応しています:圧縮->最小/低速、インターレースなし:いいえ。 また、Unityは、初期ファイル形式に関係なく、すべてのPNGをこの形式にトランスコードします。



JPG写真



実験では、JPGイメージがそのサイズ比例してアセンブリサイズに寄与することが明確に示されました 。 アセットがJPG形式の場合のUnityの動作はまだ明確ではありません。 同じ(最初の)画像をJPGで保存し、ファイルシステム上に非常に小さなファイル(75 Kバイト)を取得しました。 ただし、アセンブリでは、法外な767 KB(*)が必要でした。



多数の異なる写真で実験を行いましたが、ここでは研究のごく一部を紹介します。 逆に、他の実験では、すべてのファイルをPNGからJPGに変換することで、アセンブリの合計サイズを削減できました。

この現象の理由はまだ特定されていません。

最も可能性が高いのは、Unityの内部形式が再び発生することですが、魔法のようなUnityメカニズムとJPGアセットの相互作用の正確な原理はまだ明らかにされていません。



JPGを使用する別の方法を以下に説明します。



結論

  1. どうやら、Unityは画像の保存形式と画像の特性の両方を考慮し、いくつかの内部原則に従って圧縮を実行します。
  2. 1つの原則は完全に明確です。同じ形式の画像は、ファイルシステム上のサイズに直接比例する(ただし等しくない)アセンブリサイズに影響します


インポート設定は、ドックに記載されているとおりにアセンブリサイズに正確に影響します(画像が良いほど、アセンブリサイズへの寄与が大きくなります)。 ここに公開されている隠し機能はありません。 (他の画像形式ではまだ実験が行われていません。)





サウンドの場合、2つのインポート設定が重要です: Audio FormatForceToMono



WAV形式のファイルは、MP3形式のファイルよりもアセンブリで多くのスペースを使用します(アセンブリサイズへの寄与は、ファイルサイズとほぼ同じです)。 ForceToMono = trueに設定すると、ステレオWAVファイルが占有するスペースが少なくなります 。 インポートする前でもファイルを「モノ」に変換すると、まったく同じ効果が得られます(その場合、ForceToMonoはインスペクターで使用できません)。



ただし、WAVファイルのインポート設定AudioFormat = Compressedを設定すると、アセンブリでは、対応する最高品質のMP3ファイル(Audacity:可変ビットレート、220〜260 kbps)と同じくらいのスペースを占有します。 つまり、UnityはサウンドをMP3形式に独立してエンコードします。



同じ形式のファイルの場合、アセンブリサイズに直接比例する寄与の原則が適用されます。



他のインポート設定は、アセンブリサイズに影響しません。 これらは、RAM内のサウンドが占めるスペースの量に影響します。



目標達成のための具体的な手順



  1. 可能であれば、ソースグラフィックファイルのサイズと品質を下げます

    (1-a)透明領域のトリミング。

    私たちのゲームでは、画像の周囲に印象的な透明部分を持つ多くの写真が使用されました。 透明領域はファイルサイズを数パーセントしか増加させず、アセンブリのサイズには実際には影響しません(ただし、102xのかなり大きな写真をトリミングすると2 MB節約されます)。 ただし、透過領域ではRAMの使用が増加します(画像がBMPで表示されるため)。



    したがって、ヒント: RAMの負荷を減らすには

    *画像の透明部分を広く避けてください。

    *特にNGUIで、透明な領域が広いアトラスを作成しないでください。



    (しかし、私たちはメイントピックから注意をそらしています。)



  2. 透明度がなく、最高品質で表示される画像の場合、インポート設定で[詳細設定]- > [RGB24]を設定する必要があります。 RGBA32は意味がありませんが、自動Truecolorを残すことはお勧めしません。(経験からわかるように)RGBA32として認識される可能性があるためです。 また、これは、透明な領域がない場合は完全に冗長です(アセンブリに重量を追加し、RAMの使用を増やします)。
  3. スキームに従ってインポート設定で画質を下げます。32ビット-> 24ビット-> 16ビット 。画質レベルが許容範囲内にあることを確認します。
  4. 許容可能な品質を維持しながら、これが可能な画像のmaxTextureSizeを制限します。
  5. ビルドプロセスの前に、リソースフォルダー内の未使用のアセットを慎重に手動で削除します。 Resourcesフォルダー内のアセットの場合、Inspectorで割り当てられていなくても、Unityはそれらを自動的に削除しません。
  6. JPG画像の場合:ファイル拡張子をバイトに変更すると、TextAssetに変わります。 次に、 Texture2D.LoadImage()関数を使用して画像をロードします。 この関数はプロセッサをロードするため、非常に高速にロードする必要がある大きな画像には適さない可能性があることに注意してください。 ただし、この方法は多くの場合、アセンブリを驚くほど簡単にします。
  7. サウンドファイルサイズを可能な限り最小サイズに縮小します(品質要件を考慮して)。 可能な限りMP3を使用しますが、WAVは使用しません。 ただし、最高品質のMP3が必要な場合は、インポート設定AudioFormat = Compressed (Unityが独自に再コーディングする)でWAVファイルを使用することもできます。 可能であれば、ステレオではなくモノを使用してください。 WAVファイルの場合-インポート設定ForceToMono = trueを設定します


各項目を完了した後、得られた効果を確認することをお勧めします。 Unityの動作にはまだ魔法があるからです。



dllに関するいくつかの言葉



このドキュメントには、アセンブリに必ず含まれるdllがリストされており、追加のdll (特に重いDLL )の最小限に抑えることが求められています 。 特に、可能であれば、System.dllを使用しないでください(APKに2 MBを追加します)。 ただし、このライブラリのメソッドへの参照を避けても、 System.dllは必須です。Mono.Security.dllによってプルされるため、 System.dllは(Unity 4.5.5以降)アセンブリ含まれています。 したがって、 この時点でのUnity公式ドキュメントは完全には関連していないことがわかります



ただし、アセンブリサイズを小さくするために、他の(オプションの)DLLの使用は避けてください。



今日は以上です。 ご清聴ありがとうございました!



(この資料を研究の多かれ少なかれ体系的な結果と考えてください。行動への普遍的なガイドではありません。コメント、観察、建設的な批判、反対、提案、追加に非常に満足しています。議論中の問題を解決するために他の会社から。)



All Articles