6.3 KiB
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<UStaticMesh> MeshPtr;
运行时创建
- 创建FAssetBudleData结构体对象。
- 调用UAssetManager的AddDynamicAsset函数。
- 使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<UWorld> ZoneToUse;
/** The blueprint class used to represent this zone on the map */
UPROPERTY(EditDefaultsOnly, Category=Visual, meta=(AssetBundles = "Menu"))
TAssetSubclassOf<class AFortTheaterMapTile> 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中,进入如下设置:
每个选项的具体功能请参考文档。 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<FStringAssetReference> 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());