前一段时间其实就做完了这个资源预加载的功能,仅仅是根据以往的经验完成的这项功能。最近稍微有一点时间,就把UE4资源加载和缓存的整体流程进行了分析,这样可以对整个UE4资源管理流程有更深入的了解,同时也让想了解这部分的小伙伴们节省些时间。
一、资源定义
1、想了解整个资源加载和缓存流程,首先就要了解UE4对资源是如何定义的。在文件夹中对应uasset,在内存中对应为UPackage。这两个名词大家应该都不陌生。game中我们具体使用的都不是他们,使用的其实是Texture2D、SkeletalMesh,也有可能是一个自定义的蓝图资源等等这些具体的资源类型。
2、在UE4中有一个Outer的概念,UPackage类似一个大的集合,他包含具体的UObject。 UPackage是具体UObject的Outer。要知道资源自身数据UObject的内容,必须先知道UPackage才可以。
3、UPackage序列化到本地之后就是uasset文件,uasset是本地的资源文件。包括如下:
File Summary 文件头信息
Name Table 包中对象的名字表
Import Table 存放被该包中对象引用的其它包中的对象信息(路径名和类型)
Export Table 该包中的对象信息(路径名和类型)
Export Objects 所有Export Table中对象的实际数据。
两个UPackage实例存在依赖关系,序列化到uasset文件的时候,这些依赖关系就存储为ImportTable。可以把ImportTable看做是这个资源所依赖的其他资源的列表,ExportTable就是这个资源本身的列表。 Export Objects 所有Export Table中对象的实际数据。
4、在UPackage内容理解清楚了,其实就是如何把这些东西加载到游戏内的一个问题了,这样又引出了另一个类FLinkerLoad,这些加载这些内部UPackage信息的流程都在FLinkerLoad内,后面分析代码时,我会一一截出重点。
二、资源加载
1、FLinkerLoad 文件加载,开始位置在FLinkerLoad::Tick内,其中包括加载ImportTable、ExportTable 、ExportObjects 。
FLinkerLoad::Tick 执行完成,UPackage已经在内存中了。想了解ImportTable、ExportTable 、ExportObjects都是如何加载的直接跟FLinkerLoad::Tick 就行,流程很清晰。
FLinkerLoad::Tick函数,是UPacakge主要加载函数
2、上面介绍了基本的缓存知识,下面介绍一下如果是在项目中应用,我们该如何使用。需要缓存资源首先要先拿到资源的引用全路径名或者UPackage Name,例如:/Game/Effect/Texture/Noise/T_Noise_1007.T_Noise_1007(全路径名)或/Game/Effect/Texture/Noise/T_Noise_1007(UPackage Name)。当这个拿到后可以使用StaticLoadObject或LoadObject或RequestAsyncLoad 进行提前缓存。这三个标准函数执行过,对应的UPackage都会加载入内存。也达到了提前缓存的目的。
3、为什么提前缓存这个大家应该都了解他的好处,可以避免同步加载卡顿。那我分享一下我现在项目的资源加载流程,首先我们自己写了工具提前采集了资源的引用全路径名,在进入战斗关卡前使用RequestAsyncLoad将战斗关卡需要的资源异步加载入内存。进入战斗关卡后当需要资源时,先使用了FindObject<UObject>(ANY_PACKAGE, *ObjPath);查询成功返回,查询失败LoadObject<UObject>(InWorldContext, *ObjPath)。通过这样的方式可以完成最快拿到内存资源。这里大家肯定有疑问为什么要FindObject,LoadObject内应该是集成了FindObject的功能了才对。事实上LoadObject确实集成了FindObject的功能,但是我为什么要这样做呢?其实是有原因的,因为通过查看源码发现,如果我直接使用LoadObject而不是,采用FindObject与LoadObject的组合形式会降低效率。因为LoadObject内有一步先查找UPackage,然后在查找对应的UObject。如果资源已经在内存,FindObject可以不查找UPackage直接完成对UObjec资源t的查找,提升查找效率。
4、代码分析截图
先进行查询,查询成功返回,查询失败LoadObject
LoadObject的两步检索
查找资源对应的UPackage
FindObject会直接进行UObject资源检索,省略掉前面的UPackage检索,提升查找效率
参考文献:
https://www.jianshu.com/p/179aef406368
https://www.dazhuanlan.com/2019/11/18/5dd230d80a187/
https://zhuanlan.zhihu.com/p/35925797