Unity目前有四种资源加载方式(个人接触到的,基于2019 LTS):

  • Resources
  • AssetBundle
  • Addressable
  • AssetDatabase

本文内容刚更新到Resoureces部分接口。

Resources
Resources类允许找到并且访问对象包括资产。提供了加载和卸载资产的方式。

加载:

  • Resources.Load
  • Resources.LoadAll
  • Resources.LoadAsync

Resources.Load:

  • public static T Load(string path); 可以通过地址加载范型单个资产
  • public static Object Load(string path); 通过地址加载单个Object资产
  • public static Object Load(string path, Type systemTypeInstance); 通过地址加载并且限制资产的类型。
    这里要清楚可以加载什么资产类型。以及如何映射unity中的资产类型。

现在以加载一张Sprite类型的贴图为例子:
调用Resources.Load之前的Texture Memory

调用Resources.Load之后的Texture Memory:

注意:不管是否有变量接收加载接口的返回值。只要调用了加载接口,就会将相应的资源加载到内存中。

卸载:

  • Resources.UnloadAsset
  • Resources.UnloadUnusedAssets

Resources.UnloadAsset:

  • public static void UnloadAsset(Object assetToUnload); 卸载指定的资源

卸载操作流程,将资源加载到内存中后,使用协程在1s 后卸载。此过程中没有任何地方用到该贴图。可以看到贴图正常卸载。

现在定义临时变量接收加载的Texture贴图并附加到UI的Image上面,进行卸载操作,发现调用接口,可以正常卸载,此时UI的表现为原来贴图变成了透明,但是还存在对贴图的sprite的引用。

经过一段时间发现,内存再次上涨,但是UI仍处于透明状态,手动将Image物体关闭打开后,发现正常显示贴图。在Image物体未激活的状态下,测试结果相同。Image组件本身处于未激活状态的时候,测试结果相同。

现在再次重复上次卸载步骤,并在卸载前将Image组件的Sprite引用置为Null,发现可以正常卸载。并且内存并不会再次上涨。
Tip:现在用一个类成员变量接收加载的Texture贴图并附加到UI的Image上面,并且进行卸载操作,在卸载前将Image组件的Sprite引用置为Null,发现可以正常卸载,并且无内存升高。5s后将类成员变量关联到Image组件的sprite上,正常显示贴图,内存回升。这里只做加载卸载过程的一个流程查看,对于不同的类型资产,以及夹在卸载的原理会在其他文章中再做进一步探究。

Resources.UnloadUnusedAssets:

  • public static AsyncOperation UnloadUnusedAssets();

从Unity官方文档描述来看,首先这是一个异步卸载操作。卸载没有用到的资产。该操作会遍历Hierarchy中所有的游戏物体对象以及脚本组件还有静态变量关联的资产,不会遍历栈中的引用,以及需要注意在内存中被修改的资产,在垃圾回收之前进行 EditorUtility.SetDirty 的调用。

直接加载贴图资源,不做引用,1s后进行卸载操作,发现正常卸载。用临时变量接收资产,不做引用,发现正常卸载。符合Unity的说明。
但是用类成员变量引用的资产,没有正常卸载,符合unity的说明。

个人更觉得这是个补充那些使用了但是没有记录并且忘记卸载的资产的一个操作。应该会比较耗时,因为要遍历场景中的游戏对象,脚本以及静态变量。但是是所以不做深入探究。后续根据需要进一步深入。

本文地址:https://blog.csdn.net/weixin_37753983/article/details/110139651