https://blog.csdn.net/UWA4D/article/details/97903612
これはユ・タイガー・テクノロジー585件の記事は、著者の川魚の飼料に感謝です。共有に転送ようこそ、作者の許可なしに転載しないでください。あなたが任意の洞察力や調査結果を持っている場合も、一緒に探検するために私達に連絡する歓迎。(QQ群:793 972 859)
ます。https:ホームページで//www.zhihu.com/people/yu-jiang-3-65/、Uスパークルイベント参加者の著者、UWAは、あなたが持っているこの段階をUスパークルの開発者プログラムの開発に参加するより多くの友人を歓迎するより素晴らしいです!
AssetStudioの人気が、プロジェクトで使用AssetBundle Unityシステムリソースは、白のユーザアンパック抽出のすべての種類、したがってセキュリティAssetBundleリソースパックは、私たちの注意を喚起していることができます。
過去には、公式文書を通じて、我々主に資源パケットの暗号化を達成するためにAssetBundle.LoadFromMemory(非同期)プログラムを通じて、この方法の公式ドキュメントが記載されています。
バイト配列からAssetBundleを作成するには、このメソッドを使用します。あなたが暗号化と暗号化されていないバイトからAssetBundleを作成する必要を使用してデータをダウンロードしているときに便利です。
LoadFromMemoryAsyncと比較すると、このバージョンでは、同期であり、それはAssetBundleオブジェクトを作成完了するまで戻りません。
ここではサンプルコードの公式文書では、次のとおりです。
UnityEngine使用して、
使用UnityEngine.Networkingと、
にSystem.Collectionsを使用して、
パブリッククラスでExampleClass:MonoBehaviour
{
バイト[] MyDecription(バイト[]バイナリ)
{
バイト[] = DECRYPTED新しい新しいバイト[1024];
リターンDECRYPTED;
}
のIEnumeratorスタート()
{
UnityWebRequest.Get UWR = VAR( "HTTP://myserver/myBundle.unity3d");
収率uwr.SendWebRequestリターン();
バイト[] = decryptedBytes MyDecription(uwr.downloadHandler.data);
AssetBundle.LoadFromMemory(decryptedBytes);
}
}
。なお、公式AssetBundleのfoudamentalsの記事でAssetBundle.LoadFromMemory(非同期)のために、この方法は、公式と非常に明確に状態:
ユニティの勧告は、このAPIを使用することではありません。
AssetBundle.LoadFromMemoryAsyncはマネージコードのバイト配列(C#でバイト[])からAssetBundleをロードします。それは、常にネイティブメモリの新しく割り当てられた、連続したブロックに、マネージコードのバイト配列から元のデータをコピーします。AssetBundleはLZMA圧縮されている場合はコピーしている間、それはAssetBundleを解凍します。非圧縮とLZ4圧縮AssetBundlesはそのままコピーされます。
APIによって作成されたネイティブメモリ内の1つのコピー、およびAPIに渡された管理されたバイト配列内の1つのコピー:このAPIによって消費されるメモリのピーク量は、少なくとも二回AssetBundleのサイズになります。このAPIを介して作成AssetBundleからロードされた資産は、したがって、メモリに3回複製されます:マネージコードのバイト配列で一度、資産自体のAssetBundleのネイティブ・メモリーのコピーとGPUで三時間またはシステムメモリに一度。
ユニティ5.3.3以前は、このAPIはAssetBundle.CreateFromMemoryとして知られていました。その機能は変更されていません。
公式の説明から、我々が推奨されていない、非常に高価な使用AssetBundle.LoadFromMemory(非同期)を見ることができる自然なことです。しかし、簡単に白いユーザーを防ぐようなツールAssetStudioを使用して、それAssetBundle資源を抽出するAssetBundleに暗号化、にこれ以上の効率的かつ便利な方法はありますか?
最後に表示ユニティAPIは、それがLoadFromFileメソッドオフセットパラメータ、使用は、それが何であるかの、その後のパラメータを持っていることが分かりましたか?これは、直接AssetStudioはそれを抽出AssetBundleリソースを防ぐのに役立つことができますか?インターフェイス説明公式ドキュメントを見てください:
パブリック静的AssetBundle LoadFromFileメソッド(文字列パス、UINT CRCに沿ってオフセット)。
パラメーター
戻り値は、
失敗した場合にロードAssetBundleオブジェクトまたはnullをAssetBundle。
説明
に同期は、ディスク上のファイルからAssetBundleをロードします。
関数は、任意の圧縮タイプの束をサポートしています。LZMA圧縮の場合には、データがメモリに解凍されます。非圧縮とチャンク圧縮バンドルは、ディスクから直接読み取ることができます。
LoadFromFileAsyncと比較すると、このバージョンでは、同期であり、それはAssetBundleオブジェクトを作成完了するまで戻りません。
これはAssetBundleをロードするための最速の方法です。
サンプルコードは、公式文書が運ばないので、ここで、デモoffestパラメータを提供しなかった、そして私はデモを行うには、独自のテストコードを書くために使用します。
まず、我々は次のように、AssetBundle XAssetは、すべてのファイルを介し終了後ユニティAssetBundleをパッケージ化するファイルの内容を処理オフセット良いの生成ファイルを追加し、オフセットをカバーする必要があります。
foreachの(bundleNamesの文字列bundleNameを)
{
ストリングファイルパス= outputPath + "/" + bundleNameを。
//利用ハッシュコード做偏移
ストリングのハッシュコード= manifest.GetAssetBundleHash(bundleNameを).ToString();
ULONGは= Utility.GetOffset(ハッシュコード)オフセット。
(オフセット> 0)であれば
{
バイト[] FILEDATA = File.ReadAllBytes(ファイルパス)。
INT filelen =((INT)+ filedata.Lengthオフセット)。
バイト[]バッファ=新しいバイト[filelen]。
copyHead(FILEDATA、バッファ、(UINT)オフセット)。
copyTo(FILEDATA、バッファ、(UINT)オフセット)。
FileStreamをFS = File.OpenWrite(ファイルパス)。
fs.Write(バッファ、0、filelen)。
fs.Close();
オフセット+ =ファイルパス+ "オフセット:" +オフセット+ "\ n"は、
}
WriteItem(ストリーム、bundleNameを、ファイルパス、ハッシュコード);
}
私たちは、その後のテストをロードし、我々は、パラメータは、負荷、復号化、およびシミュレーションファイルメモリからロードして、テクスチャ缶を表示するため、その中にAssetBundleを読み取るために使用されるAssetBundleを相殺されました次のコードを参照します。
//基于オフセット加载AssetBundle
空隙onLoadWithOffsetClicked非同期()
{
(offsetBundle)場合
offsetBundle.Unload(TRUE)。
VAR CURRENT_MEMORY = Profiler.GetTotalAllocatedMemoryLong()。
display_image.texture = NULL;
VARパス= System.IO.Path.Combine(Application.streamingAssetsPath、 "assets_previews_offset")。
VAR assetBundleRequest = AssetBundle.LoadFromFileAsync(パス、0、294);
await assetBundleRequest;
VARテクスチャ= assetBundleRequest.assetBundle.LoadAsset <にTexture2D>( "download.jpg");
display_image.texture =テクスチャ;
offsetBundle = assetBundleRequest.assetBundle。
DEBUG.LOG( "完全な偏荷重:" +(Profiler.GetTotalAllocatedMemoryLong() - CURRENT_MEMORY));
}
//基于Menmory加载AssetBundle
非同期ボイドonLoadWithMemoryClicked()
{
IF(memoryBundle)
(真)memoryBundle.Unload。
VAR CURRENT_MEMORY = Profiler.GetTotalAllocatedMemoryLong()。
display_image.texture = NULL;
VARパス= System.IO.Path.Combine(Application.streamingAssetsPath、 "assets_previews")。
WWW WWW =新しいWWW( "ファイル://" +パス);
await WWW;
VAR要求= AssetBundle.LoadFromMemoryAsync(www.bytes)。
await要求。
VARテクスチャ= request.assetBundle.LoadAsset <にTexture2D>( "download.jpg");
display_image.texture =テクスチャ;
memoryBundle = request.assetBundle。
www.Dispose();
DEBUG.LOG(「ロード完了メモリー:」+(Profiler.GetTotalAllocatedMemoryLong() - CURRENT_MEMORY));
}
次に、我々は、上記2つのサンプルのプロファイラデータ解析機能を実行した結果を見て:
スクリーンショットのテストシナリオ
ロードする前にオフセットパラメータメモリ条件を使用します
ロードAssetBundle後のオフセットパラメータメモリの状況を使用します
LoadFromMemory前に、使用メモリの負荷状況
LoadFromMemory負荷後の使用メモリの状況
比較すると、LoadFromMemoryメモリの使用が大幅に増加が起こった、とローディングプロセス中にもピークメモリが登場しました。
我々はAssetBundleは、理論的にバインドされているリソースをシフトしなければならなかったので、私たちの理論は実践の試練に耐えるならば、AssetStudio我々は解決できない直接ユニティプロジェクトAssetBundleは、次に我々は、見てください。
テストした後、あなたは簡単にAssetStudioプレビューAssetBundleのリソースを使用することができたときにオフセット増加しなかった(コードに対処する必要があるプロジェクトとリソースの企業のため)、図を参照してください。
結果は、オフセット資源の発見と私たちの理論的な推測と一致している、を参照してください。