Unity的資源加載與卸載


有三種資源加載方式:

1.靜態引用。具體操作:創建public變量,把文件掛到物體上,在Inspector里把相應資源給public變量,用的時候instantiate或者直接用。

2.Resources.Load。加載Resources文件夾下的資源,加載后instantiate.

3.AssetBundle.Load。加載打包后的資源。

前兩種資源加載方式,對於引用對象是在instantiate時加載的,而不是在加載時直接加載的,所以有時會造成第一次加載時客戶端卡。

第三種資源加載方式,在加載時會加載所有引用資源,instantiate時只是生成克隆。

 

說到Unity資源的卸載,就需要先了解要卸載什么。其實就是要卸載資源所占用的內存,使資源占用的內存釋放。

資源所占用內存的形式一般是三種:

1.assetbundle文件內存鏡像占用的內存,在加載assetbundle文件完成后,會在內存中形成assetbundle文件的內存鏡像,同一個assetbundle文件不能有兩個內存鏡像,所以同一個assetbundle文件在沒有Unload之前不能再次加載。

2.從assetbundle文件中加載出來的資源所占的內存(AssetBundle.Load多次Load只會有一份資源內存占用)。(指GameObject,Texture,Sprite,Shader,Material)如果從assetbundle里加載的資源是引用類型的,就不需要實例化就可以直接使用,並且如果有多個地方使用同一個引用資源時,引用資源不需要實例化,比如:Texture,Sprite,Shader,Material就是引用類型的。如果assetbundle里加載的資源不是引用句類型,不能直接使用,需要實例化后使用,如:GameObject,需要Instantiate實例化后使用。如果需要多個GameObject,需要多次實例化。

3.Instantiate實例化的資源所占用的內存。(一般是指GameObject)

AssetBundle.UnLoad(false);卸載1的內存占用。

AssetBundle.UnLoad(true);卸載1,2的內存占用(所有此AssetBundle已經加載的資源)。

如果想要只卸載某個已經加載的資源,用Resources.UnLoadAsset(obj)(只能用這個卸載引用資源);Resources.UnloadUnusedAsset()卸載沒有被引用的所有的資源。

Destroy主要用來銷毀3的內存占用,即銷毀克隆對象,也可用於銷毀靜態物體,不會自動釋放該對象的所有引用。Destroy不能用來銷毀從文件加載的資源(會刪除相應的資源文件,報錯Destroying assets is not permitted to avoid data loss.)

加載新場景時會自動銷毀2,3的內存占用,但是1的內存占用不會銷毀,1只能通過AssetBundle.Unload去釋放。

一般的加載流程:

  1.創建assetbundle(WWW www = new WWW(url))

  2.用AssetBundle.Load加載需要的資源

  3.判斷資源的種類,根據種類去選擇下一步操作(可把資源分為共享資源和非共享資源,或者根據使用頻率選擇是否保存已經加載過的資源等)

  4.確保加載完成后,調用AssetBundle.Unload(false)去卸載1創建出的鏡像文件。

一般的釋放流程:

  1.如果克隆了對象,用Destroy去銷毀。

  2.在合適的地方調用Resources.UnloadUnusedAsset(),釋放已經沒有引用的資源(就是沒有地方在用的資源,引用計數為0)

  3.如果是想卸載單獨的一個用Load加載的資源,用Resources.UnloadAsset(obj)釋放(只能用這個卸載引用資源)

  4.如果想要立即釋放調用GC.Collect()。

一個容易出錯的例子:

UnityEngine.Object obj = Resources.Load("MyPrefab");

GameObject instance = Instantiate(obj) as GameObject;
Destroy(instance);
Resources.UnloadUnusedAssets();

這時,內存並沒有釋放掉,因為MyPrefab還被obj這個變量所這用。

obj = null;

Resources.UnloadUnusedAssets();

這樣才能真正釋放

Resources.UnloadUnusedAssets()不但要沒有實際物體引用,也要沒有被生命周期內的變量所引用,才可以釋放。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM