Published on

资源注册模块AssetRegistry分析

Authors
  • avatar
    Name
    东哥
    Twitter

有的时候我们需要对当前工程下的特定资源进行一些操作,比如找到所有图片资源或者所有静态模型资源,然后把这些资源信息发到某个UI上进行操作等等

本文对UE4资源注册模块AssetRegistry进行简单的分析

目前蓝图已经封装了相应的库,可以非常方便的调用

Asset Registry模块负责处理引擎下的资源信息(收集/检索*.uasset),从这个模块中可以读取到所有资源信息(FAssetData)

FAssetData

主要参数

/*Obj的具体路径,比如 /Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter*/
	FName ObjectPath;
//比如/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter
	FName PackageName;
//比如: /Game/ThirdPersonCPP/Blueprints/
	FName PackagePath;
//资源名称
	FName AssetName;
//资源class的名称,如果是蓝图则是Blueprint
	FName AssetClass;
/*
UProperty的名称和值的键值对
可以从此获取一些描述信息,比如蓝图资源的BlueprintType等
*/
	FAssetDataTagMapSharedView TagsAndValues;
//ChunkID
	`TArray<int32>` ChunkIDs;

在获取Asset的时候需要填充一个结构体参数FARFilter,里面的参数部分类似上述参数,之后再看

FARFilter

对资源进行检索的时候的过滤参数

//参考FAssetData
	`TArray<FName>` PackageNames;
//参考FAssetData
	`TArray<FName>` PackagePaths;
//参考FAssetData
	`TArray<FName>` ObjectPaths;
//参考FAssetData
	`TArray<FName>` ClassNames;
//白名单,蓝图不可见
	TMultiMap<FName, `TOptional<FString>`> TagsAndValues;
//黑名单
	RecursiveClassesExclusionSet;
//是否递归查找路径
	bool bRecursivePaths;
//是否递归查找类继承
	bool bRecursiveClasses;
//是否只查询磁盘上的资源
	bool bIncludeOnlyOnDiskAssets;
	

比较需要注意的是ClassNames这个参数,这个类型并不是我们场景中对象的类型,打个比方,我们场景里的玩家一般是ACharacter,但是我们的资源其实就是Blueprint,所以在填充这个结构体的时候并不能用*.::StaticClass()来给与Class类型

一般情况资源的创建类型就是用右键创建出来的名称或类似的名称,并且都是继承自Object

FAssetRegistryState

储存了读取asset后的相关信息,用作磁盘内容的cache数据,用于描述asset registry当前的状态,可以由IAssetRegistry进行使用和维护。把这些数据单独组成一个FAssetRegistryState类,是为了减少耦合性,因为引擎中除asset registry外的其他模块 也需要用到这些数据。

主要方法

我们可以通过static TScriptInterface GetAssetRegistry();获取单例

蓝图亦可以

image-20201127165818065

static UObject* GetAsset(const FAssetData& InAssetData);

通过上述方法可以自定义的根据FARFliter参数来获取所需的资源数据

如果不清楚每个参数的含义,可以反向的通过下面方法来查看

static FAssetData CreateAssetData(const UObject* InAsset, bool bAllowBlueprintClass = false);

	bool GetAssetsByPackageName(FName PackageName, `TArray<FAssetData>`& OutAssetData, bool bIncludeOnlyOnDiskAssets = false) const;
	bool GetAssetsByPath(FName PackagePath, `TArray<FAssetData>`& OutAssetData, bool bRecursive = false, bool bIncludeOnlyOnDiskAssets = false) const;
	bool GetAssetsByClass(FName ClassName, `TArray<FAssetData>`& OutAssetData, bool bSearchSubClasses = false) const;

上面三个方法根据不同方式来获取对应的资源

void GetSubPaths(const FString& InBasePath, `TArray<FString>`& OutPathList, bool bInRecurse) const;

基于一个基础路径获取子路径,比较有用


	 bool GetReferencers(FName PackageName, `TArray<FName>`& OutReferencers, EAssetRegistryDependencyType::Type InReferenceType = EAssetRegistryDependencyType::Packages) const;
	 bool GetDependencies(FName PackageName, `TArray<FName>`& OutDependencies, EAssetRegistryDependencyType::Type InDependencyType = EAssetRegistryDependencyType::Packages) const;

获取引用和依赖关系,也很有用


	void SearchAllAssets(bool bSynchronousSearch);
	void ScanFilesSynchronous(const `TArray<FString>`& InFilePaths, bool bForceRescan = false);
	void ScanPathsSynchronous(const `TArray<FString>`& InPaths, bool bForceRescan = false);
//等等

扫描/搜索文件,不需要返回值,因为扫描以后文件就保存在FAssetRegistryState内了