異步加載
Resources和AB包的同步加載與異步加載對比代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class AsyncLoad : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){//Resources的同步異步加載代碼//同步加載代碼//GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite = Resources.Load<Sprite>("EXP");//通過開啟協同,執行最后一個異步Resources加載資源//StartCoroutine(LoadImage());//AB包的同步異步加載代碼//AssetBundle ab = AssetBundle.LoadFromFile(Config.ABPath + "/test2");//GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite=ab.LoadAsset<Sprite>("EXP");StartCoroutine(LoadAB());}IEnumerator LoadImage(){//開啟一個異步加載ResourceRequest rr = Resources.LoadAsync<Sprite>("EXP");//協同會在加載資源成功后,繼續執行(底層封裝了線程加載資源)yield return rr;//將加載成功的資源,顯示出來GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite = rr.asset as Sprite;}IEnumerator LoadAB(){AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Config.ABPath + "/test2");yield return abcr;GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite = abcr.assetBundle.LoadAsset<Sprite>("EXP");}
}
????????想要區分是否成功執行異步加載,可以在運行游戲前開啟暫停鍵,之后運行,若跨幀實現圖片加載功能(第一幀圖片為白圖,下一幀圖片加載出指定圖片),則證明成功實現了異步加載功能。
內存分析
以Unity2021版的Profiler視窗為例(建議同學們也打開自己的視窗自行觀察):
我們選擇Profiler視窗中的Memory,并運行游戲觀察其實時操作的內存占用情況。
(個人理解)
?通過Memory Profiler圖觀察,在以AB包為例觀察其各功能在運行時內存的占用情況可知(本次測試觀察Graphics&Graphics Driver),當僅加載AB包時,其內存會短暫出現短幅上升又下降的情況(該AB包為默認壓縮狀態,此過程可說明AB包在解壓),最終下降到趨于運行無操作時內存占用量,說明加載AB包在運行時并不實際占用內存;而當加載圖片時,內存占用量增加,此情況說明當AB包加載資源并顯示到游戲界面時,才實際占用內存;當我們卸載AB包不銷毀圖片時,該張圖片占用的內存不會被釋放,而當我們重新加載AB包資源并加載其他圖片覆蓋未被銷毀的圖片,其圖片會作為游離資源存放在內存中。
原因:Unity的回收機制為"懶回收"機制,它默認不會回收此類游離資源,若實際開發項目需要考慮內存情況,建議自行編寫回收機制(但不建議過于頻繁回收)決定何時回收此類游離資源,釋放內存。
編寫以上測試的代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Memory : MonoBehaviour
{AssetBundle ab;public Image image;public void LoadFile(){ab = AssetBundle.LoadFromFile(Config.ABPath + "/bigtest");}public void LoadImage(){image.sprite = ab.LoadAsset<Sprite>("PanelTest");}public void UnLoadFile(){//參數代表,是否將場景中通過AB包加載出來的資源,同AB包一起銷毀ab.Unload(false);}public void Recycling(){//將所有沒有再使用的資源進行回收Resources.UnloadUnusedAssets();}
}
場景視圖及層級面板情況:
該系列專欄為網課課程筆記,僅用于學習參考。