AnimationClipのABファイルサイズ

今回の主な話題：AnimationClipのABファイルサイズ、異なるUnityバージョンのABファイルサイズは不一致、ABの前後にパックされたCRC値は不一致。

---
###アセット管理
Q1：最近パッケージの圧縮を行っています。一部のアニメーションファイルのAssetBundleファイルが比較的大きいことがわかりました。その原因は含まれているクリップの数が多いですから。しかし、これらのクリップはすべて再利用され、ただアニメーショントラックに掛かっているイベントが異なるから、作ってあげます。
LZ4の圧縮形式を使用し、ファイルのサイズは約800K +です。偶然にLZ4以外の形式を使って、このファイルのサイズは約60Kです。違いは10倍以上ので、おかしいです。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/7600cc07-d671-f949-b0b9-bd002e3f8ebe.png)
他のプロジェクトでこのような問題が発生したかどうかはわかりませんが、 理論から理解してみました：
このような繰り返しアニメーションでは、データを再利用でき、アニメーションイベントは追加の配置を保存することと同じであるため、理論的には、このような再利用されたClipsを追加しても、AssetBundleファイルに大きな影響はありません。
私の推測が正しいですか？この場合、この部分の体積を圧縮するための良い方法はありますか？
>この問題の存在可能性があります。 LZ4圧縮を採用しているアニメーションファイルAssetBundleのサイズは、アニメーションパネル内のClips数と各Clipsのサイズに関連あります。
ソースコードが見えないので、自分の見解を述べます：AssetBundleをパッケージするときにLZ4圧縮を選択すると、アニメーションファイル内の各Clipが独立アセットとして圧縮され、解凍時に必要なClipだけを解凍するようになれます。ただし、こうすれば異なるClip間の重複データの再利用を遮断しますので、AssetBundleの体積がClip数の増加により大きくなります。簡単な例は、同じClipを複数追加した場合、Clip数が増えるにつれてAssetBundleファイルも増えることです（アニメーションFbxのサイズを超えやすい）。
デフォルトのLZMA圧縮では、AssetBundleが一つの全体として圧縮され（もちろん、解凍するときも全体的に解凍する必要があります）、異なるクリップ間で繰り返されるデータは完全に再利用できます。それで、圧縮されたAssetBundleのサイズは分割されたClipへの影響は大きくないです。同じ例で、アニメーションファイルに複数のClipを追加した後、LZMAで圧縮したAssetBundleのサイズはまだ小さいです。異なるClipの数を増加しても、サイズは基本的に同じままです。
そうしたら、圧縮によってアニメーションファイルAssetBundleの体積を削減したい場合、解凍速度に影響小さいアニメーションファイルにLZMAを使用して圧縮できます。

---
###アセット管理
Q2：Unity 5.3.8と5.6.5で同じ設定を使用しましたが、FBX後のサイズの差が非常に大きいのはなぜですか？
Unity 5.3.8 ：35K，
Unity 5.6.5 ：400K。
>問題主のAssetBundleファイルを見て、下記の手がかりを提供できます。
Unity 5.6のBundle：
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/917e9683-499c-6ca5-7af5-17830eb0c565.png)
Unity 5.3のBundle：
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/87956987-7337-0ab1-fd02-9cb510883b4c.png)
二つのBundleの違いはShaderにあることがわかりました。そしてUnity 5.5アップデートに次の文が確認できます。
`Shaders: Shaders are now exported to the Unity player completely in binary. There is no Shader text string and parsing in run time.`
つまり、Unity 5.6のBundleのShaderはバイナリにコンパイルされていますが、Unity 5.3のBundleはまだテキストのShaderであり、Bundleの違いにつながります。

---
###アセット管理
Q3：シーンをパッケージする後のAssetsBundleが毎回異なります。Strippt Shaderの設定も変更し、毎回同じ空シーンにパックしましたが、パックされたCRC値が違うです。
最初にローカルリソースを削除するたびに、SVNからCheckOutしてパッケージします。シーンに使用されるシェーダーは独立のBundleにパッケージし、このシェーダーパッケージも異なります。また、Unity 5.6.2のパッケージAPIは、ただ一つのBundle Nnameによってパッケージされた関数です。パッケージするほどにシーンを切り替えることができません。
>まず、同じリソースが複数回パッケージする場合、確かにMD5は異なります。この問題は以前のUnityのロードマップで言及されていましたが、現在は見つかりません。新しいバージョンで解決される可能性があることを示しています。
しかし、以前のバージョンでは、シーンのAssetBundleを引き起こす可能性のある2つの既知のMD5変化があり、1つは問題主が言及された問題（Shader Stripping）で、もう1つはStatic Batchingを開いた後の毎回パッケージ時に生成されたCombined Mesh（またはその順序）は異なる状況があります。もちろん、他の理由があるかもしれません。
だから、AssetBundleのHash値によって内容が変更されたかどうかを判断することをお勧めします（Shader Strippingの問題によりHashが変更しますが、Combined Meshの問題によりHash値が変更されません）、またはAppendHashToAssetBundleNameオプションを使用して直接Hash値をAssetBundleのサフィックスとしてチェックできます。

---
###その他
Q4：すみません、WWWまたはUnityWebRequestがドメイン名を介してAssetBundleをダウンロードするときに、どうすればアセットの実際のIPアドレスを知れますが？
Dns.GetHostAddressesを使ってIPが変更しているため、WWWが実際に接続しているIPが前回Dns.GetHostAddressesで取得したIPと保証できません。やりたいのは、logクライアントが異なる地域で接続するCDNノードIPとアセットのダウンロード速度を記録することです。
>本来でも、ドメイン名とIP自体は1対1の関係ではありません。一つのドメイン名は、複数のAレコードまたはCNAMEレコードを解析できます（CDNなど）。
Dns.GetHostAddressesが取得するのは、ドメイン名に対応するAレコード情報です、digコマンドの出力を参照できます。一般的に、返されたIPをトラバースして、個別に使ってみられます。
WWWまたはUnityWebRequestの内部はどうやってこれを実現とは不明ですが、取得された最初のIPのみを処理する、または成功まで各IPを試行し続き可能性があります。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

UWA公式サイト：https://jp.uwa4d.com
UWA公式ブログ：https://blog.jp.uwa4d.com