リソースの読み込み(ResourcesとAssetBundle)とメモリ管理に関するUnity3D



Unity3d About Resource Loading Resources



Unity3Dには2つの動的ロードメカニズムがあります。1つはResources.Loadで、もう1つはAssetBundleを介したものです。実際、この2つの違いはわずかです。 Resources.Loadは、デフォルトのパッケージでAssetBundleからリソースをロードすることです。通常、AssetBundleファイルは自分で作成し、実行時に動的にロードする必要があり、パスとソースを指定できます。

実際、シーン内のすべての静的オブジェクトにもこのような読み込みプロセスがありますが、Unity3Dの背景は自動的に完成します。



詳細を教えてください:
AssetBundleランタイムロード:
ファイルから、CreateFromFileを使用します(このメソッドはスタンドアロンプ​​ログラムにのみ使用できることに注意してください)これは最速のロードメソッドです。
CreateFromMemory(byte [])を使用すると、メモリから取得することもできます。このバイト[]は、ファイル読み取り、wwwダウンロード、またはその他の可能な方法のバッファから取得できます。
実際、WBW AssetBundleは、内部データが読み取られた後、assetBundleを自動的に作成します。
作成後は、ハードディスクまたはネットワーク上のファイルをメモリの領域に読み込むのと同じです。現時点では、これは単なるAssetBundleメモリミラーデータブロックであり、Assetsの概念はありません。
アセットの読み込み:
AssetBundle.Loadを使用します(Resources.Loadと同じ)。これにより、AssetBundleのメモリイメージからAssetオブジェクトが読み取られて作成されます。 Assetオブジェクトを作成し、対応するメモリをストレージに割り当てます(逆シリアル化)
AssetBundle.LoadAsyncを使用した非同期読み取り
AssetBundle.LoadAllで複数回読み取ることもできます
AssetBundleのリリース:
AssetBundle.Unload(flase)は、AssetBundleファイルを解放するメモリイメージであり、Loadによって作成されたAssetメモリオブジェクトは含まれていません。
AssetBundle.Unload(true)は、AssetBundleファイルのメモリイメージを解放し、Loadで作成されたすべてのAssetメモリオブジェクトを破棄します。

プレハブはassetBundleから読み込まれ、次のものが含まれる場合があります。ゲームオブジェクト変換メッシュテクスチャマテリアルシェーダースクリプトおよびその他のさまざまなアセット。
クローン(レプリケーション)+参照をアセットと組み合わせるプロセスであるプレハブをインスタンス化すると、GameObjectトランスフォームはクローンが新しく生成されます。他のメッシュ/テクスチャ/マテリアル/シェーダーなど。これらは、テクスチャとTerrainDataを含む純粋に参照された関係、およびメッシュ/マテリアル/ PhysicMaterialを含む参照とレプリケーションです。参照されたAssetオブジェクトはコピーされず、ロードされたAssetオブジェクトへの単純なポインターだけがコピーされます。あいまいな参照とクローンのこの混合は、おそらくほとんどの人を混乱させる主な理由です。
特筆すべきは特別なことです。スクリプトアセット、奇妙に見えます。Unityのすべてのスクリプトは閉じたクラス定義であり、呼び出し元のコードを記述していません。ライトクラスの定義スクリプトは機能しません。実際のUnityエンジンは呼び出し元のコードであり、スクリプトアセットのクローンを作成すると新しいクラスインスタンスになり、インスタンスが作業を完了します。 Unityメインスレッドのコールチェーンにハングアップすると、ClassインスタンスのOnUpdateOnStartが実行されます。複数のオブジェクトが同じスクリプトをハングします。実際、スクリプトクラスの複数のインスタンスが複数のオブジェクトにハングしているため、理解しやすいです。新しいクラスのプロセスでは、データ領域がコピーされ、コード領域が共有され、特別なコピーと参照の関係になります。
次に、同じプレハブ、またはこのメッシュ/テクスチャ/マテリアル/シェーダーをインスタンス化できます...新しいGameObjectsなどがありますが、Textureなどの新しい参照オブジェクトは作成されません。 。
したがって、ロードするアセットは実際にはデータソースであり、新しいオブジェクトを生成したり参照したりするために使用されます。生成のプロセスは、クローンまたは参照のいずれかです。
インスタンスを破棄するときは、それらのクローンオブジェクトを解放するだけで、参照オブジェクトとクローンのデータソースオブジェクトは解放されません。 Destroyは、それらのオブジェクトを参照する他のオブジェクトがあるかどうかを知りません。 。
ゲームシーンオブジェクトがなくなるまで待ちます。これらのアセットを使用すると、これらのアセットは参照なしで無料のデータブロックになります。 UnusedAssetsです。現時点では、Resources.UnloadUnusedAssetsによって解放できます。破棄はこのタスクを実行できません。AssetBundle.Unload(false)も機能しません。AssetBundle.Unload(true)も機能しますが、これらのアセットを使用しているオブジェクトがないことがわかっている場合を除き、安全ではありません。
理解を深めるための写真付き:





アセットと呼ばれますが、コピーや参照とは異なります。これはUnityの暗い技術的な詳細でカバーされており、自分で理解する必要があります。

メモリ管理について
従来のプログラミングの考え方によれば、最善の方法は、すべてのオブジェクトを自分で保守し、キューを使用してすべてのオブジェクトを保存し、宛先であるアンロード自体を使用することです。
しかし、これはC#.netフレームワークでは少し不要であり、非常に面倒です。
確かにあなたはこの方法で管理することができます

作成時:
www、ファイル、メモリのいずれからでも、最初にAssetBundleを作成します
AssetBundle.loadを使用して必要なアセットをロードします
ロード直後、AssetBundle.Unload(false)は、AssetBundleファイル自体のメモリイメージを解放しますが、ロードされたAssetオブジェクトを破棄しません。 (この方法では、AssetBundleへの参照を保存する必要がなく、すぐにメモリを解放できます)
リリース時:
Instantiateオブジェクトがある場合は、Destroyで破棄します
必要に応じてResources.UnloadUnusedAssetsを呼び出して、参照されていないアセットを解放します。
すぐにメモリを解放してGC.Collect()を追加する必要がある場合、メモリがすぐに解放されないことがあり、メモリが多すぎて例外が発生することがあります。
これにより、最小限の使用量で常にタイムリーにメモリが解放されます。ロードされた各オブジェクトを参照する必要もありません。



もちろん、これが唯一の方法ではありません。ロードとリリースの原則に従っている限り、何でもできます。

システムが新しいシーンをロードすると、AssetBundle.LoadでロードしたオブジェクトやInstaniateクローンを含む、すべてのメモリオブジェクトが自動的に破棄されます。ただし、Unloadで解放する必要があるAssetBundleファイル自体のメモリミラーは含まれていません。 .netの用語では、このデータキャッシュは管理されていません。

さまざまなロードと初期化の使用法を要約します。
AssetBundle.CreateFrom .....:AssetBundleメモリイメージを作成します。Unloadなしでは同じassetBundleファイルを再度使用できないことに注意してください。
WWW.AssetBundle:もちろん、上記と同じですが、使用する前に、まずリターンを再生成する必要があります
AssetBundle.Load(name):指定された名前のアセットをAssetBundleから読み取り、Assetオブジェクトを生成します。同じ名前のオブジェクトを複数回ロードすると、最初の場合を除いて、生成されたオブジェクトのみが返されます。 Assetオブジェクト、つまり、Assetを複数回ロードしても、複数のコピー(シングルトン)は生成されません。
Resources.Load(path&name):上記と同じですが、デフォルトの場所からロードされます。
Instantiate(object):Cloneオブジェクトのすべてのコンポーネントとサブオブジェクト(公式ドキュメントを参照)を含むオブジェクトの完全な構造であるshallow Copyは、すべての参照型をコピーするわけではありません。特別な使用法がありますが、ほとんど使用されませんが、Instantiateを使用して、テクスチャなどの参照タイプのアセットを完全にコピーできます。コピーするテクスチャは、読み取り/書き込み可能に設定する必要があります。

さまざまなリリースを要約する
破棄:主に、複製されたオブジェクトを破棄するために使用されます。シーン内の静的オブジェクトにも使用できます。オブジェクトへのすべての参照が自動的に解放されるわけではありません。アセットにも使用できますが、コンセプトは同じではありません。ファイルからロードされたAssetオブジェクトを破棄し、対応するリソースファイルを破棄する場合は注意してください。ただし、破棄されたアセットがコピーであるか、スクリプトによって動的に生成された場合、メモリオブジェクトのみが破棄されます。
AssetBundle.Unload(false):AssetBundleファイルのメモリイメージを解放します
AssetBundle.Unload(true):AssetBundleファイルのメモリイメージを解放し、ロードされたすべてのAssetsメモリオブジェクトを破棄します。
Reources.UnloadAsset(Object):ロードされたAssetオブジェクトを明示的に解放します。ディスクファイルによってロードされたAssetオブジェクトのみがアンロードされます。
Resources.UnloadUnusedAssets:参照なしですべてのアセットオブジェクトを解放するために使用されます
GC.Collect()は、ガベージコレクターにメモリをただちに解放するように強制します。 UnityのGC機能は良くありません。よくわからない場合は、強制的に呼び出してください。

元の投稿アドレス:http://www.cnblogs.com/88999660/archive/2013/03/15/2961663.html

リソースの読み込み。AssetBundleとResourcesの間に本質的な違いはありません。リソースは実際にはUnity内のAssetBundleとしてパッケージ化されています。多くのゲームでは、ホットアップデートのためにリモートサーバーからアップデートリソースをダウンロードする必要もあります。
これは、リモートエンドまたはローカルクライアントからローカルリソースとリモートリソースのバージョン番号をダウンロードすることで比較できます。異なるプラットフォーム上のローカルリソースの保存場所は、次のように異なります。
UNITY_ANDROID:” jar:file://” + Application.dataPath +“!/ assets / xxx.assetbundle”
UNITY_IPHONE:Application.dataPath +“ /Raw/xxx.assetbundle”
UNITY_STANDALONE_WINまたはUNITY_EDITOR: 'file://' + Application.dataPath +
「/streamingAssets/xxx.assetbundle」

Xxxはファイル名です。


パブリックデリゲートvoidDelVoid()
パブリックデリゲートvoidDelAsset(アセットアセット)
パブリックデリゲートvoidDelOnBundleLoad(Object bundle)

public bool LoadAsset(string resURL、DelAsset onLoad)
{{

If(serverVersionInfo [bundleName]> LocalVersionInfo [bundleName])//バージョン番号を比較する
{{
resURL = RemotePath + bundleName
version = LocalVersionInfo [bundleName]
}

StartCoroutine(LoadBundle(resURL、(bundle)=> {
if(バンドル)
{{
アセットアセット=アセットとしてバンドル
if(onLoad!= null)
onLoad(asset)
}
}))
trueを返す
}

IEnumerator LoadBundle(string url、DelOnBundleLoad onResLoad = null)
{{
WWW www = null
www = WWW.LoadFromCacheOrDownload(url、version)

イールドリターンwww

if(www.error!= null)
{{
イールドブレイク
}

if(onResLoad!= null)
onResLoad(www.assetBundle.mainAsset)

www.assetBundle.Unload(false)
} 123456789101112131415161718192021222324252627282930313233343536373839404142

ここでは、WWW.LoadFromCacheOrDownload()を使用してリモートクライアント(ローカルリソース)をダウンロードします。このメソッドの具体的な機能は次のとおりです。
1. Unityはまず、ローカルの「url」ファイルがあるかどうかを判断します。そうでない場合は、URLに従って対応するファイルをダウンロードします。次に、ファイルをローカルに保存し、対応するバージョン番号を記録します。
2. Unityは最初にローカルの「url」ファイルを判別します。ローカルのバージョン番号はAPIのバージョン番号よりも小さく、Unityも最新のファイルをダウンロードしてから、ローカルを上書きします。このファイルは最新のバージョン番号で記録されます。 。
3. Unityは、最初に「url」を含むファイルをローカルで判別します。ローカルバージョン番号は、APIによって渡されたバージョン番号以上です。 Unityはそれをローカルから直接取得し、対応するファイルをロードします。ファイルが返されます。

Chcheは、ゲームのインストールディレクトリではなく、ローカルハードドライブのディレクトリの下に存在します。ローカルにダウンロードされたリソースは、Caching.CleanCache()を介して削除できます。
バージョン比較方法はここには書かれていません。各AssetBundleのバージョン番号は、構成ファイルを介して保存できます。サーバーが更新された後、ローカルクライアントはリモートバージョン番号情報を取得し、次にローカルクライアントを取得します。バージョン番号が比較され、ダウンロードがダウンロードされた後、ローカルバージョン番号が更新されます。

---------------------

この記事は、fenrir_sunのCSDNブログからのものです。全文アドレスについては、次をクリックしてください:https://blog.csdn.net/fenrir_sun/article/details/50207909?utm_source = copy