我想这样做: 创建并打包原始游戏。然后,我想基于原始游戏中的蓝图,使用新的网格/声音/动画和蓝图创建其他PAK文件。原始游戏应该不了解其他网格/动画/等内容。因此,我需要在原始游戏中使用AssetRegistry创建一个智能系统来扫描所有PAK文件,然后加载/装入文件,并使用AssetRegistry扫描那些PAK文件中的所有资产。
我为实现自己的目标所做的事情: 我为目标平台(Windows独立)成功创建并打包了原始游戏。然后,在项目中,我创建其他内容并将其烹饪为目标平台。我使用UnrealPak.exe创建PAK文件以获取其他内容。我可以通过将PAK文件放置在Paks文件夹中来在原始游戏中加载/加载PAK文件,并且它们在游戏启动时进行加载/加载(这句话基于原始游戏中的LOG文件,我不知道如何检查是否正确)。我甚至可以使用FCoreDelegates :: OnMountPak.Execute使用代码加载/加载PAK文件(这句话也基于原始游戏的LOG文件)。因此,加载/挂载PAK文件应该可以正常工作。但是现在最大的问题在哪里。我想使用AssetRegistry扫描所有PAK文件中的所有资产。我尝试了一切。我尝试了ScanPathsSynchronous方法,GetAllAssets方法。只会发生什么事,它会从原始游戏PAK文件中加载资产。看来AssetRegistry对其他PAK文件一无所知。我试图告诉AssetRegistry这些带有AddPath方法的文件在哪里,但仍然无法正常工作。
所以我尝试的示例代码在这里:
FString path1 = FPaths::ConvertRelativePathToFull(FString("../../../TestPaks/Content/Paks/test.pak"));
FString path2 = FPaths::ConvertRelativePathToFull(FString("../../../TestPaks/Content/Paks/testmaterial.pak"));
bool check1 = false;
bool check2 = false;
if (FCoreDelegates::OnMountPak.IsBound())
{
check1 = FCoreDelegates::OnMountPak.Execute(path1, 0, nullptr); //Number should be 0-4; specifies search order
check2 = FCoreDelegates::OnMountPak.Execute(path2, 0, nullptr); //Number should be 0-4; specifies search order
}
UE_LOG(LogTemp, Warning, TEXT("%s"), *path1);
UE_LOG(LogTemp, Warning, TEXT("%s"), *path2);
FString NewString1 = check1 ? "true" : "false";
FString NewString2 = check2 ? "true" : "false";
UE_LOG(LogTemp, Warning, TEXT("check 1 = %s"), *NewString1);
UE_LOG(LogTemp, Warning, TEXT("check 2 = %s"), *NewString2);
FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(FName("AssetRegistry"));
IAssetRegistry& assetRegistry = AssetRegistryModule.Get();
TArray<FString> ContentPaths;
TArray<FAssetData> data;
//assetRegistry.AddPath(path1);
FString contentRelativeDir = TEXT("/Game/Paks");
assetRegistry.AddPath(contentRelativeDir);
assetRegistry.ScanPathsSynchronous({ contentRelativeDir });
//assetRegistry.SearchAllAssets(true);
assetRegistry.GetAllAssets(data, false);
assetRegistry.GetAllCachedPaths(ContentPaths);
for (FString& data : ContentPaths)
{
UE_LOG(LogTemp, Warning, TEXT("GetAllCachedPaths: %s"), *data);
}
FString NewString = FString::FromInt(data.Num());
UE_LOG(LogTemp, Warning, TEXT("%s"), *NewString);
for (int32 i = 0; i < data.Num(); i++)
{
FString s = data[i].AssetName.ToString();
FString ss = data[i].AssetClass.ToString();
UE_LOG(LogTemp, Warning, TEXT("%s | %s"), *s, *ss);
}
我尝试了很多版本的路径,但没有任何效果。我在大约两周的时间里陷入了混乱,对于如何做以及将如何工作,我没有更多的提示。那么这应该如何正常工作呢???我在这里的论坛和StackOverflow上找到了一些解决方案,但是它们不再起作用了。
答案 0 :(得分:0)
我已经从.pak文件加载了资产,但是我使用FStreamableManager而不是AssetRegistry。 我将描述我的工作...
1)挂载.pak文件:我只需要将其他.pak文件放到WindowNoEditor / [Project_Name] / Content / Paks /文件夹中(假设您打包了window),游戏引擎就会自动挂载该.pak文件。
2)从该.pak文件加载/获取资产:
FPakPlatformFile *PakPlatformFile;
FString PlatformFileName = FPlatformFileManager::Get().GetPlatformFile().GetName();
if (PlatformFileName.Equals(FString(TEXT("PakFile"))))
{
PakPlatformFile = static_cast<FPakPlatformFile*>(&FPlatformFileManager::Get().GetPlatformFile());
}
else
{
PakPlatformFile = new FPakPlatformFile;
if (!PakPlatformFile->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT("")))
{
UE_LOG(LogTemp, Error, TEXT("FPakPlatformFile failed to initialize"));
return;
}
FPlatformFileManager::Get().SetPlatformFile(*PakPlatformFile);
}
TArray<FString> ArrAllMountedPakFile;
PakPlatformFile->GetMountedPakFilenames(ArrAllMountedPakFile);
for (int32 i = 0; i < ArrAllMountedPakFile.Num(); i++)
{
FString PakFileName = ArrAllMountedPakFile[i];
FString PakFilePathFull = FPaths::ConvertRelativePathToFull(PakFileName);
FPakFile PakFile(PakPlatformFile, *PakFilePathFull, false);
TArray<FString> FileList;
FString MountPoint = PakFile.GetMountPoint();
PakFile.FindFilesAtPath(FileList, *MountPoint, true, false, true);
for (int32 i = 0; i < FileList.Num(); i++)
{
FString AssetName = FileList[i];
FString AssetShortName = FPackageName::GetShortName(AssetName);
FString FileName, FileExt;
AssetShortName.Split(TEXT("."), &FileName, &FileExt);
FString NewAssetName = TEXT("/Game/<path_to_asset>/") + FileName + TEXT(".") + FileName;
FSoftObjectPath StrNewAssetRef = NewAssetName;
FStreamableManager AssetLoader;
UObject* NewLoadedObject = AssetLoader.LoadSynchronous(StrNewAssetRef);
if (NewLoadedObject)
{
// do something, cast to compatible type.
}
}
}
希望能对您有所帮助。加油!