117 lines
6.3 KiB
Markdown
117 lines
6.3 KiB
Markdown
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;
|
||
```
|
||
##### 运行时创建
|
||
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<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());
|
||
``` |