异步加载
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();}
}
场景视图及层级面板情况:
该系列专栏为网课课程笔记,仅用于学习参考。