ue4获取依赖

发布时间 2023-06-26 11:15:56作者: liuxiaobei556

添加 编辑器偏好设置->额外启动参数 添加 -ForceDependsGathering 参数
项目名.uproject
添加AssetRegistry内容

	"Modules": [
		{
			"Name": "项目名",
			"Type": "Runtime",
			"LoadingPhase": "Default",
			"AdditionalDependencies": [
				"Engine"
			]
		},
		{
			"Name": "AssetRegistry",
			"Type": "Runtime",
			"LoadingPhase": "PostEngineInit"
		}
	],

c++类目录修改项目.Build.cs

项目
..Private
....MyRsyncLevelAssetManager.cpp
..Public
....MyRsyncLevelAssetManager.h
..项目.Build.cs

项目.Build.cs 添加AssetRegistry

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "AssetRegistry", })

代码示例

MyRsyncLevelAssetManager.h

#pragma once

#include "CoreMinimal.h"
#include "Engine/AssetManager.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/IAssetRegistry.h"
#include "Engine/StreamableManager.h"
#include "Kismet/GameplayStatics.h"
#include "MyRsyncLevelAssetManager.generated.h"

DECLARE_DYNAMIC_DELEGATE(FOnPackageLoaded);
/**
 *
 */
UCLASS(Blueprintable)
class WARGAME_SANGUO_API UMyRsyncLevelAssetManager : public UAssetManager
{
	GENERATED_BODY()

public:
	bool bIsLoaded;
	//FString CurrentLoadPackage;

	FStreamableManager AssetLoader;

	TSoftObjectPtr<UObject> SoftObjectPtr;
	//输出依赖信息
	//FString OutDependenciesName;
	//输出流式传输加载项
	FString RequestAsyncLoadDebugName;
	//输出依赖项路径
	TArray<FSoftObjectPath> depAssets;
	//输出依赖项

	TArray<FAssetDependency> MyOutDependencies;

	//TSharedPtr<FStreamableHandle> CurrentStreamableHandle;
public:
	UFUNCTION(BlueprintPure, CallInEditor, DisplayName = "MyRsyncLevelAssetManager")
		static UMyRsyncLevelAssetManager* Get();

	UFUNCTION(BlueprintCallable, CallInEditor)
		TArray<FSoftObjectPath> MyAsyncLoadObject(FSoftObjectPath Path, FOnPackageLoaded OnPackageLoaded);
	UFUNCTION(BlueprintCallable, CallInEditor)
		float GetCurrentLoadProgress(int32& LoadedCount, int32& RequestedCount) const;
	UFUNCTION(BlueprintCallable, CallInEditor)
		bool CheckSoftObjectPathArrayLoadingStatus(const FSoftObjectPath& AssetPaths);
};

MyRsyncLevelAssetManager.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "MyRsyncLevelAssetManager.h"

//创建句柄对象
TSharedPtr<FStreamableHandle> CurrentStreamableHandle;
FString CurrentLoadPackage;
UMyRsyncLevelAssetManager* UMyRsyncLevelAssetManager::Get() {

	UMyRsyncLevelAssetManager* This = Cast<UMyRsyncLevelAssetManager>(GEngine->AssetManager);
	if (This)
	{
		return This;
	}
	else
	{
		return NewObject<UMyRsyncLevelAssetManager>(); // never calls this
	}
}

TArray<FSoftObjectPath> UMyRsyncLevelAssetManager::MyAsyncLoadObject(FSoftObjectPath Path, FOnPackageLoaded OnPackageLoaded) {
	//FParse::Param(FCommandLine::Get(), TEXT("ForceDependsGathering"));
	FString result;
	bIsLoaded = false;
	// 获取FStreamableManager的引用
	//FStreamableManager& MyStreamableManager = GetStreamableManager();

	// 获取AssetRegistry单例
	FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
	AssetRegistryModule.StartupModule();
	IAssetRegistry& AssetRegistry = AssetRegistryModule.Get();


	//开始异步搜索所有资产
	AssetRegistryModule.Get().SearchAllAssets(true);
	// 等待资产注册表完成加载依赖项
	while (AssetRegistryModule.Get().IsLoadingAssets()) {
		FPlatformProcess::Sleep(0.1f);
	}

	CurrentLoadPackage = Path.ToString();
	// 运行查询
	//TArray<FAssetDependency> MyaOutDependencies;

	//依赖项查询对象
	UE::AssetRegistry::FDependencyQuery MyQuery;
	MyQuery.Required = UE::AssetRegistry::EDependencyProperty::None;
	//检索所有类型的依赖项
	//UE::AssetRegistry::EDependencyCategory::All

	
	bool bResult = IAssetRegistry::Get()->GetDependencies(FAssetIdentifier(*Path.ToString()), MyOutDependencies, UE::AssetRegistry::EDependencyCategory::All, MyQuery);
	//bool bResult = AssetRegistry.GetDependencies(FAssetIdentifier(*Path.ToString()), MyOutDependencies);
	//bool bResult = AssetRegistryModule.Get().GetDependencies(FName(Path.ToString()), MyOutDependencies);
	//result = "MyOutDependencies error";
	
	// 存储要加载的资源以及其所有依赖项的路径
	//TArray<FSoftObjectPath> depAssets;

	// 如果查询成功,将依赖项加入数组
	if (bResult)
	{
		for (const FAssetDependency& Dependency : MyOutDependencies)
		{
			//将所有依赖项添加到depAssets数组中
			depAssets.Add(FSoftObjectPath(Dependency.AssetId.ToString()));
			FString depresult = TEXT("StartLoad:\t" + FString::FromInt(depAssets.Num()) + Dependency.AssetId.ToString());
			UE_LOG(LogTemp, Log, TEXT("查询到的依赖: %s"), *depresult);
		}
	}


	// 添加要加载的资源到depAssets数组中
	depAssets.Add(Path);
	//添加加载提示词
	RequestAsyncLoadDebugName = TEXT("加载资源组");
	// 调用FStreamableManager的RequestAsyncLoad函数发起异步加载请求
	//CurrentStreamableHandle = UAssetManager::GetStreamableManager().RequestAsyncLoad(depAssets, [=] {OnPackageLoaded.ExecuteIfBound(); }, 0, true, false, RequestAsyncLoadDebugName);
	
	//UE_LOG(LogTemp, Log, TEXT("关卡加载中状态: %s"), *RequestAsyncLoadDebugName)
	LoadPackageAsync(
		CurrentLoadPackage,
		FLoadPackageAsyncDelegate::CreateLambda([=](const FName& PackageName, UPackage* LoadedPackage, EAsyncLoadingResult::Type Result)
			{
				if (Result == EAsyncLoadingResult::Succeeded)
				{
					//可执行通知进行地图切换,即openlevel
					bIsLoaded = true;
					UE_LOG(LogTemp, Warning, TEXT("游戏关卡加载成功"));
					OnPackageLoaded.ExecuteIfBound();
				}
			}), 0, PKG_ContainsMap);

	return depAssets;
}

float UMyRsyncLevelAssetManager::GetCurrentLoadProgress(int32& LoadedCount, int32& RequestedCount) const {
	return GetAsyncLoadPercentage(*CurrentLoadPackage);
	//if (CurrentStreamableHandle.IsValid())
	//{

	//	CurrentStreamableHandle->GetLoadedCount(LoadedCount, RequestedCount);
	//	return CurrentStreamableHandle->GetProgress() * 100.f;
	//	//return 15.f;
	//}
	//return 0.f;
}

bool UMyRsyncLevelAssetManager::CheckSoftObjectPathArrayLoadingStatus(const FSoftObjectPath& AssetPath) {
	FString result = FString::Printf(TEXT("正在加载 %s"), *RequestAsyncLoadDebugName);
	//for (const FSoftObjectPath& AssetPath : AssetPaths)
	//{
		//从AssetPath中获取UObject对象指针,并使用ResolveObject函数检查其加载状态
	if (UAssetManager::GetStreamableManager().IsAsyncLoadComplete(AssetPath))
	{
		UE_LOG(LogTemp, Warning, TEXT("资产 %s 已加载"), *AssetPath.ToString());
		return true;
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("资产 %s 仍在加载"), *AssetPath.ToString());
		return false;
	}

		//UObject* Asset = AssetPath.ResolveObject();
		//if (Asset == nullptr)
		//{
		//	UE_LOG(LogTemp, Warning, TEXT("资产 %s 仍在加载"), *AssetPath.ToString());
		//}
		//else if (Asset->IsPendingKillOrUnreachable())
		//{
		//	UE_LOG(LogTemp, Warning, TEXT("资产 %s 等待回收或者不可达"), *AssetPath.ToString());
		//}
		//else
		//{
		//	UE_LOG(LogTemp, Warning, TEXT("资产 %s 已加载"), *AssetPath.ToString());
		//}
	//}
	//return result;
}