打开ProjectSettings→ AssetManager
添加一种类型
资源定义的代码:
// 只要继承了UObject的类
// 都会有个virtual FPrimaryAssetId GetPrimaryAssetId() const override;
// 因此必须实现这个接口才能在AssetManager里被找到
#include "Engine/AssetManager.h"
// ==== 示例A UI ====
// LoginPanel.h
class ULoginPanel : public UUserWidget {
public:
virtual FPrimaryAssetId GetPrimaryAssetId() const override;
}
// LoginPanel.cpp
FPrimaryAssetId ULoginPanel::GetPrimaryAssetId() const {
FPrimaryAssetId id(FPrimaryAssetType(FName("与2.一样的名字")), FName("必须是每个实例唯一的名字"));
return id;
}
// ==== 示例B SO ====
// Bullet.h
class UBullet : public UPrimaryAssetData {
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyGame")
int typeID;
virtual FPrimaryAssetId GetPrimaryAssetId() const override;
}
// Bullet.cpp
FPrimaryAssetId ULoginPanel::GetPrimaryAssetId() const {
FPrimaryAssetId id(FPrimaryAssetType(FName("bullet"), FName(*FString::FromInt(typeID)));
return id;
}
加载资源的代码:
UAssetManager *assetManager = UAssetManager::GetIfInitialized();
const FPrimaryAssetType mapType(FName("Entity"));
TArray<FPrimaryAssetId> assetIds;
bool has = assetManager->GetPrimaryAssetIdList(mapType, assetIds);
if (has) {
// 从硬盘里加载资源到内存, 注: 这个方法是异步的
handle = assetManager->LoadPrimaryAssets(assetIds);
handle->WaitUntilComplete(); // 阻塞异步
// 当游戏结束时, 记得 handle.Reset()
for (auto &assetId : assetIds) {
// 加载非蓝图类, 例如: UTexture2D、自定义的 UPrimaryDataAsset
// 可以理解为相当于加载 Unity 的 ScriptableObject
FAssetData assetData;
has = assetManager->GetPrimaryAssetData(assetId, assetData);
if (has) {
SJLog("AssetData: " + assetData.AssetName.ToString());
}
// 加载蓝图类
// 注: AEntityRole 是我自定义的类, 继承于 AActor
auto role = assetManager->GetPrimaryAssetObjectClass<AEntityRole>(assetId);
if (role != nullptr) {
GetWorld()->SpawnActor<AEntityRole>(role);
SJLog("Role: " + role->GetClass()->GetName());
}
}
}
查看资源表:
https://www.youtube.com/watch?v=9MGHBU5eNu0&ab_channel=UnrealEngine







