GetResourceAcquireProgress 加载进度函数。 文档地址: https://docs.unrealengine.com/zh-CN/Engine/Basics/AssetsAndPackages/AssetManagement/index.html 谁允许你直视本大叔的 的Blog: - https://blog.csdn.net/noahzuo/article/details/78815596 - https://blog.csdn.net/noahzuo/article/details/78892664 #### 简述 AssetManager可以使得开发者更加精确地控制资源发现与加载时机。AssetManager是存在于编辑器和游戏中的单例全局对象。 #### Primary Assets、Secondary Assets与Primary Asset Labels AssetManagementSystem将资源分为两类:**PrimaryAssets**与**SecondaryAssets**。 ##### PrimaryAssets **PrimaryAssets**可以通过,调用GetPrimaryAssetId()获取的**PrimaryAssetID**对其直接操作。 将特定UObject类构成的资源指定**PrimaryAssets**,需要重写GetPrimaryAssetId函数,使其返回有效的一个有效的FPrimaryAssetId结构。 ##### SecondaryAssets **SecondaryAssets**不由AssetManagementSystem直接处理,但其被PrimaryAssets引用或使用后引擎便会自动进行加载。默认情况下只有UWorld(关卡Asset )为主资源;所有其他资源均为次资源。 将**SecondaryAssets**设为**PrimaryAssets**,必须重写GetPrimaryAssetId函数,返回一个有效的 FPrimaryAssetId结构。 #### UAssetManager与FStreamableManager UAssetManager是一个单例对象,负责管理主资源的发现与加载。FStreamableManager对象也被包含在其中,可以用来执行异步加载资源。通过FStreamableHandle(它是一个智能指针)来控制资源的生命周期(加载与卸载)。 与UAssetManager不同,FStreamableManager可以建立多个实例。 #### AssetBundle AssetBundle是与主资源相关特定资源的命名列表。使用 ``` meta = (AssetBundles = "TestBundle") ``` 对UObject中的TAssetPtr类型成员变量或FStringAssetReference中的成员变量的UPROPERTY代码进行标记,即可完成创建。例如: ``` UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Display, AssetRegistrySearchable, meta = (AssetBundles = "TestBundle")) TAssetPtr MeshPtr; ``` ##### 运行时创建 1. 创建FAssetBudleData结构体对象。 2. 调用UAssetManager的AddDynamicAsset函数。 3. 使PrimaryAssets的ID与AssetBundle中的SecondaryAssets关联起来。 #### 从硬盘中加载PrimaryAssets 程序员可以通过继承UPrimaryDataAsset(它的父类是UDataAsset,拥有加载和保存内置资源束数据的功能)的方式来控制ContentBrowser中的Asset(PrimaryAssets)。 下面是一个使用UPrimaryDataAsset的范例,它告诉引擎进入什么地图需要什么资源。 ``` /** A zone that can be selected by the user from the map screen */ UCLASS(Blueprintable) class FORTNITEGAME_API UFortZoneTheme : public UPrimaryDataAsset { GENERATED_UCLASS_BODY() /** Name of the zone */ UPROPERTY(EditDefaultsOnly, Category=Zone) FText ZoneName; /** The map that will be loaded when entering this zone */ UPROPERTY(EditDefaultsOnly, Category=Zone) TAssetPtr ZoneToUse; /** The blueprint class used to represent this zone on the map */ UPROPERTY(EditDefaultsOnly, Category=Visual, meta=(AssetBundles = "Menu")) TAssetSubclassOf TheaterMapTileClass; }; ``` ##### 注册PrimaryAssets步骤 ###### 如果项目中有自定义的UAssetManager就需要向引擎进行注册 修改引擎目录中的DefaultEngine.ini,修改[/Script/Engine.Engine]段中的AssetManagerClassName变量。 ``` [/Script/Engine.Engine] AssetManagerClassName=/Script/Module.UClassName ``` 其中“Module”代表项目的模块名,“UClassName”则代表希望使用的UClass名。在Fortnite中,项目的模块名为“FortniteGame”,希望使用的类则名为 UFortAssetManager(意味着其 UClass 命名为 FortAssetManager)所以第二行应为: ``` AssetManagerClassName=/Script/FortniteGame.FortAssetManager ``` ###### 向UAssetManager注册PrimaryAssets 方法有三: 1.在Project Settings——Game——AssetManager中,进入如下设置: ![image](https://docs.unrealengine.com/Images/Engine/Basics/AssetsAndPackages/AssetManagement/ProjectSettingsAssetManager.jpg) 每个选项的具体功能请参考文档。 2.编辑DefaultGame.ini文件:找到(或创建)一个名为 /Script/Engine.AssetManagerSettings的代码段,添加: ``` [/Script/Engine.AssetManagerSettings] !PrimaryAssetTypesToScan=ClearArray +PrimaryAssetTypesToScan=(PrimaryAssetType="Map",AssetBaseClass=/Script/Engine.World,bHasBlueprintClasses=False,bIsEditorOnly=True,Directories=((Path="/Game/Maps")),SpecificAssets=,Rules=(Priority=-1,bApplyRecursively=True,ChunkId=-1,CookRule=Unknown)) +PrimaryAssetTypesToScan=(PrimaryAssetType="PrimaryAssetLabel",AssetBaseClass=/Script/Engine.PrimaryAssetLabel,bHasBlueprintClasses=False,bIsEditorOnly=True,Directories=((Path="/Game")),SpecificAssets=,Rules=(Priority=-1,bApplyRecursively=True,ChunkId=-1,CookRule=Unknown)) ``` 3.在代码中操作:重写UAssetManager类中的StartInitialLoading函数并从该处调用ScanPathsForPrimaryAssets。因此,推荐您将所有同类型的主资源放入相同的子文件夹中。这将使资源查找和注册更为迅速。 ###### 加载资源 LoadPrimaryAssets、LoadPrimaryAsset和LoadPrimaryAssetsWithType适用于游戏启动前。 之后通过UnloadPrimaryAssets、UnloadPrimaryAsset 和 UnloadPrimaryAssetsWithType卸载。 #### 动态注册与加载PrimaryAsset ``` //从AssetId构建Asset字符串表,并且构建AssetBundle数据 UFortAssetManager& AssetManager = UFortAssetManager::Get(); FPrimaryAssetId TheaterAssetId = FPrimaryAssetId(UFortAssetManager::FortTheaterInfoType, FName(*TheaterData.UniqueId)); TArray AssetReferences; AssetManager.ExtractStringAssetReferences(FFortTheaterMapData::StaticStruct(), &TheaterData, AssetReferences); FAssetBundleData GameDataBundles; GameDataBundles.AddBundleAssets(UFortAssetManager::LoadStateMenu, AssetReferences); //通过递归的方式,展开AssetBundle数据(获取SecondaryAssets数据) AssetManager.RecursivelyExpandBundleData(GameDataBundles); // 注册动态资源 AssetManager.AddDynamicAsset(TheaterAssetId, FStringAssetReference(), GameDataBundles); // 开始预加载 AssetManager.LoadPrimaryAsset(TheaterAssetId, AssetManager.GetDefaultBundleState()); ```