BlueRoseNote/03-UnrealEngine/Gameplay/Gameplay/AssetManager/UPrimaryDataAsset与UAssetManager.md
2023-06-29 11:55:02 +08:00

117 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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中的AssetPrimaryAssets
下面是一个使用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中进入如下设置
![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<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());
```