Anonymous
Относительно ошибки неоднократно загрузки и разгрузки файлов PAK во время упаковки программы и времени выполнения
Сообщение
Anonymous » 24 апр 2025, 07:02
Извините, не поддерживает ли не поддерживать дубликатную загрузку и разгрузку файлов PAK.
После монтажа пакета PAK и создания статической сетки в файле на сцену, я удалил все ресурсы и установил PAK. Тем не менее, Windows не сразу очистила эту часть памяти. Примерно через 15-30 секунд, когда память была очищена, и я повторно выполнил логику загрузки, будет сообщена вся ошибка: < /p>
Код: Выделить всё
[2025.04.21-02.25.21:072][499]LogWindows: Error: === Critical error: ===
[2025.04.21-02.25.21:072][499]LogWindows: Error:
[2025.04.21-02.25.21:072][499]LogWindows: Error: Assertion failed: PakPrecacherSingleton [File:D:/Build/++UE4/Sync/Engine/Source/Runtime/PakFile/Private/IPlatformFilePak.cpp] [Line: 1462]
[2025.04.21-02.25.21:072][499]LogWindows: Error:
[2025.04.21-02.25.21:072][499]LogWindows: Error:
[2025.04.21-02.25.21:072][499]LogWindows: Error:
[2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ffd52cbfe7c KERNELBASE.dll!UnknownFunction []
[2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7f34e76 DBJTest.exe!UnknownFunction []
[2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7f38cb8 DBJTest.exe!UnknownFunction []
[2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7c9063d DBJTest.exe!UnknownFunction []
[2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7bf3415 DBJTest.exe!UnknownFunction []
< /code>
Вот мой код: < /p>
Версия двигателя: 4.27 < /p>
.h
#pragma once
#include "CoreMinimal.h"
#include "IPlatformFilePak.h"
#include "Engine/StaticMeshActor.h"
#include "GetPakAsset.generated.h"
UCLASS()
class DBJTEST_API AGetPakAsset : public AActor
{
GENERATED_BODY()
public:
virtual void BeginPlay() override;
TSharedPtr PakPlatform;
// TSharedFuture PakPlatform;
class IPlatformFile* OldPlatform;
TArray LoadStaticMeshActors;
TArray TestLoadStaticMesh;
TArray FoundObjects;
TArray LoadPath;
FString PakFileFullPath;
FString RootPath;
FString ContentPath;
private:
UFUNCTION(Exec, BlueprintCallable)
void GetAsset(FString InPakFullPath, FString PluginName);
void UnloadPakFile();
void GetAllFilesInPak(FPakFile& PakFile, const FString& InPath, TArray& OutFiles);
void PrintToScreen(const FString& Message, float Duration, FColor Color);
void Init();
};
< /code>
.cpp
#include "GetPakAsset.h"
#include "HAL/PlatformTime.h"
#include "IPlatformFilePak.h"
#include "Misc/DateTime.h"
#include "Engine/Engine.h"
#include "Engine/StaticMeshActor.h"
#include "PakManager.h"
// #include "memoryapi.h"
// #include "processthreadsapi.h"
void AGetPakAsset::BeginPlay()
{
Super::BeginPlay();
// OldPlatform = &FPlatformFileManager::Get().GetPlatformFile();
// PakPlatform = MakeShareable(new FPakPlatformFile());
// PakPlatform->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT(""));
// PakFileFullPath = "";
Init();
}
void AGetPakAsset::Init()
{
OldPlatform = &FPlatformFileManager::Get().GetPlatformFile();
PakPlatform = MakeShareable(new FPakPlatformFile());
PakPlatform->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT(""));
PakFileFullPath = "";
}
void AGetPakAsset::GetAsset(FString InPakFullPath, FString PluginName)
{
FDateTime LocalTime = FDateTime::Now();
FString LocalTimeString = LocalTime.ToString(TEXT("%Y-%m-%d %H:%M:%S"));
UE_LOG(LogTemp, Log, TEXT("Timestamp:%s"), *LocalTimeString);
Init();
FPlatformFileManager::Get().SetPlatformFile(*PakPlatform.Get());
PakFileFullPath = InPakFullPath;
TRefCountPtr TmpPak = new FPakFile(PakPlatform.Get(), *PakFileFullPath, false);
FString PakMountPoint = TmpPak->GetMountPoint();
#if WITH_EDITOR
RootPath = "/Game/";
#else
RootPath = "/" + PluginName +"/";
#endif
ContentPath = PakMountPoint + "Content/";
FPackageName::RegisterMountPoint(RootPath, ContentPath);
int32 Pos;
Pos = PakMountPoint.Find("Content/");
FString NewMountPoint = PakMountPoint.RightChop(Pos);
TmpPak->SetMountPoint(*NewMountPoint);
if (PakPlatform->Mount(*PakFileFullPath, 1, *NewMountPoint))
{
TArray FoundFilenames;
GetAllFilesInPak(*TmpPak, *TmpPak->GetMountPoint(), FoundFilenames);
// Function method for obtaining resource paths in old versions
//TmpPak->FindFilesAtPath(FoundFilenames, *TmpPak->GetMountPoint(), true, false, false);
UE_LOG(LogTemp, Display, TEXT("Found asset num %d"), FoundFilenames.Num());
TArray MountPaks;
PakPlatform->GetMountedPakFilenames(MountPaks);
LoadPath = FoundFilenames;
if (FoundFilenames.Num() > 0)
{
for (FString& Filename : FoundFilenames)
{
if (Filename.EndsWith(TEXT(".uasset")))
{
FString NewFileName = Filename;
NewFileName.RemoveFromEnd(TEXT(".uasset"));
int32 LocalPos = NewFileName.Find("/Plugins");
NewFileName = NewFileName.RightChop(LocalPos + 8);
#if WITH_EDITOR
NewFileName = "/Game" + NewFileName;
NewFileName = NewFileName.Replace(TEXT("/Content/"), TEXT("/"));
NewFileName = NewFileName.Replace(*(PluginName + "/"), TEXT(""));
#else
NewFileName = NewFileName.Replace(TEXT("/Content/"), TEXT("/"));
#endif
// Handle possible double slashes "//"
NewFileName = NewFileName.Replace(TEXT("//"), TEXT("/"));
UE_LOG(LogTemp, Log, TEXT("Path to load object:%s"), *NewFileName);
// Save resource path to array
FoundObjects.AddUnique(FSoftObjectPath(NewFileName).ResolveObject());
// Loaded Object
UObject* LoadedObj;// = StaticLoadObject(UObject::StaticClass(), nullptr, *NewFileName);
if (StaticLoadObject(UObject::StaticClass(), nullptr, *NewFileName))
{
LoadedObj = StaticLoadObject(UObject::StaticClass(), nullptr, *NewFileName);
}
else
{
LoadedObj = nullptr;
}
if (!LoadedObj)
return;
UStaticMesh* SM = Cast(LoadedObj);
if (SM)
{
AStaticMeshActor* MeshActor = GetWorld()->SpawnActor(AStaticMeshActor::StaticClass(), FVector(0,0,460), FRotator(0,0,0) );
MeshActor->Rename(*SM->GetName());
MeshActor->SetMobility(EComponentMobility::Movable);
MeshActor->GetStaticMeshComponent()->SetStaticMesh(SM);
AGetPakAsset::PrintToScreen(TEXT("StaticMesh load successful!"), 5.0f, FColor::White);
TestLoadStaticMesh.Add(SM);
LoadStaticMeshActors.Add(MeshActor);
// UE_LOG(LogTemp, Log, TEXT("StaticMesh load successful!"));
}
}
}
}
}
FPlatformFileManager::Get().SetPlatformFile(*OldPlatform);
}
void AGetPakAsset::GetAllFilesInPak(FPakFile& PakFile, const FString& InPath, TArray& OutFiles)
{
// Retrieve files in the current path
TArray FoundFileNames;
PakFile.FindPrunedFilesAtPath(FoundFileNames, *InPath, true, false, false);
for (const FString& Filename : FoundFileNames)
{
// Add the current file to the list
OutFiles.Add(Filename);
}
// Retrieve subdirectories under the current path
TArray Subdirectories;
PakFile.FindPrunedFilesAtPath(Subdirectories, *InPath, false, true, false); // Retrieve directory path, do not retrieve files
// Traverse subdirectories and recursively call VNet Files InPak
for (const FString& Subdirectory : Subdirectories)
{
// Recursive call to retrieve all files in the subdirectories
GetAllFilesInPak(PakFile, Subdirectory, OutFiles);
}
}
void AGetPakAsset::PrintToScreen(const FString& Message, float Duration = 5.0f, FColor Color = FColor::Blue)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(-1, Duration, Color, Message);
}
}
void AGetPakAsset::UnloadAsset()
{
if (PakPlatform.IsValid() && PakFileFullPath != TEXT(""))
{
for (int i = 0; i < LoadStaticMeshActors.Num(); i++)
{
if (!LoadStaticMeshActors[i])
continue;
LoadStaticMeshActors[i]->Destroy();
LoadStaticMeshActors[i]->ConditionalBeginDestroy(); // Forced release of resources
}
LoadStaticMeshActors.Empty();
PakFileFullPath.Empty();
// Ensure all references are released
FlushAsyncLoading();
CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS);
PakPlatform->Unmount(*PakFileFullPath);
PakPlatform.Reset();// Release PakPlatform resources
// Remove registered mount points
FPackageName::UnRegisterMountPoint(RootPath, ContentPath);
// Forcefully release PakPrecacher
// extern FPakPreca
}
}
void AGetPakAsset::UnloadPakFile()
{
// Stop all asynchronous records
FlushNetDormancy();
GEngine->ForceGarbageCollection(true);
// Uninstall the mounted Pak
if (PakPlatform.IsValid() && !PakFileFullPath.IsEmpty())
{
PakPlatform->Unmount(*PakFileFullPath);
}
// Release PakPlatform resources
PakPlatform.Reset();
// Remove registered mount points
FPackageName::UnRegisterMountPoint(RootPath, ContentPath);
// Restore original platform files
FPlatformFileManager::Get().SetPlatformFile(*OldPlatform);
}
Подробнее здесь:
https://stackoverflow.com/questions/795 ... s-during-p
1745467324
Anonymous
Извините, не поддерживает ли не поддерживать дубликатную загрузку и разгрузку файлов PAK. После монтажа пакета PAK и создания статической сетки в файле на сцену, я удалил все ресурсы и установил PAK. Тем не менее, Windows не сразу очистила эту часть памяти. Примерно через 15-30 секунд, когда память была очищена, и я повторно выполнил логику загрузки, будет сообщена вся ошибка: < /p> [code][2025.04.21-02.25.21:072][499]LogWindows: Error: === Critical error: === [2025.04.21-02.25.21:072][499]LogWindows: Error: [2025.04.21-02.25.21:072][499]LogWindows: Error: Assertion failed: PakPrecacherSingleton [File:D:/Build/++UE4/Sync/Engine/Source/Runtime/PakFile/Private/IPlatformFilePak.cpp] [Line: 1462] [2025.04.21-02.25.21:072][499]LogWindows: Error: [2025.04.21-02.25.21:072][499]LogWindows: Error: [2025.04.21-02.25.21:072][499]LogWindows: Error: [2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ffd52cbfe7c KERNELBASE.dll!UnknownFunction [] [2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7f34e76 DBJTest.exe!UnknownFunction [] [2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7f38cb8 DBJTest.exe!UnknownFunction [] [2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7c9063d DBJTest.exe!UnknownFunction [] [2025.04.21-02.25.21:072][499]LogWindows: Error: [Callstack] 0x00007ff6f7bf3415 DBJTest.exe!UnknownFunction [] < /code> Вот мой код: < /p> Версия двигателя: 4.27 < /p> .h #pragma once #include "CoreMinimal.h" #include "IPlatformFilePak.h" #include "Engine/StaticMeshActor.h" #include "GetPakAsset.generated.h" UCLASS() class DBJTEST_API AGetPakAsset : public AActor { GENERATED_BODY() public: virtual void BeginPlay() override; TSharedPtr PakPlatform; // TSharedFuture PakPlatform; class IPlatformFile* OldPlatform; TArray LoadStaticMeshActors; TArray TestLoadStaticMesh; TArray FoundObjects; TArray LoadPath; FString PakFileFullPath; FString RootPath; FString ContentPath; private: UFUNCTION(Exec, BlueprintCallable) void GetAsset(FString InPakFullPath, FString PluginName); void UnloadPakFile(); void GetAllFilesInPak(FPakFile& PakFile, const FString& InPath, TArray& OutFiles); void PrintToScreen(const FString& Message, float Duration, FColor Color); void Init(); }; < /code> .cpp #include "GetPakAsset.h" #include "HAL/PlatformTime.h" #include "IPlatformFilePak.h" #include "Misc/DateTime.h" #include "Engine/Engine.h" #include "Engine/StaticMeshActor.h" #include "PakManager.h" // #include "memoryapi.h" // #include "processthreadsapi.h" void AGetPakAsset::BeginPlay() { Super::BeginPlay(); // OldPlatform = &FPlatformFileManager::Get().GetPlatformFile(); // PakPlatform = MakeShareable(new FPakPlatformFile()); // PakPlatform->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT("")); // PakFileFullPath = ""; Init(); } void AGetPakAsset::Init() { OldPlatform = &FPlatformFileManager::Get().GetPlatformFile(); PakPlatform = MakeShareable(new FPakPlatformFile()); PakPlatform->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT("")); PakFileFullPath = ""; } void AGetPakAsset::GetAsset(FString InPakFullPath, FString PluginName) { FDateTime LocalTime = FDateTime::Now(); FString LocalTimeString = LocalTime.ToString(TEXT("%Y-%m-%d %H:%M:%S")); UE_LOG(LogTemp, Log, TEXT("Timestamp:%s"), *LocalTimeString); Init(); FPlatformFileManager::Get().SetPlatformFile(*PakPlatform.Get()); PakFileFullPath = InPakFullPath; TRefCountPtr TmpPak = new FPakFile(PakPlatform.Get(), *PakFileFullPath, false); FString PakMountPoint = TmpPak->GetMountPoint(); #if WITH_EDITOR RootPath = "/Game/"; #else RootPath = "/" + PluginName +"/"; #endif ContentPath = PakMountPoint + "Content/"; FPackageName::RegisterMountPoint(RootPath, ContentPath); int32 Pos; Pos = PakMountPoint.Find("Content/"); FString NewMountPoint = PakMountPoint.RightChop(Pos); TmpPak->SetMountPoint(*NewMountPoint); if (PakPlatform->Mount(*PakFileFullPath, 1, *NewMountPoint)) { TArray FoundFilenames; GetAllFilesInPak(*TmpPak, *TmpPak->GetMountPoint(), FoundFilenames); // Function method for obtaining resource paths in old versions //TmpPak->FindFilesAtPath(FoundFilenames, *TmpPak->GetMountPoint(), true, false, false); UE_LOG(LogTemp, Display, TEXT("Found asset num %d"), FoundFilenames.Num()); TArray MountPaks; PakPlatform->GetMountedPakFilenames(MountPaks); LoadPath = FoundFilenames; if (FoundFilenames.Num() > 0) { for (FString& Filename : FoundFilenames) { if (Filename.EndsWith(TEXT(".uasset"))) { FString NewFileName = Filename; NewFileName.RemoveFromEnd(TEXT(".uasset")); int32 LocalPos = NewFileName.Find("/Plugins"); NewFileName = NewFileName.RightChop(LocalPos + 8); #if WITH_EDITOR NewFileName = "/Game" + NewFileName; NewFileName = NewFileName.Replace(TEXT("/Content/"), TEXT("/")); NewFileName = NewFileName.Replace(*(PluginName + "/"), TEXT("")); #else NewFileName = NewFileName.Replace(TEXT("/Content/"), TEXT("/")); #endif // Handle possible double slashes "//" NewFileName = NewFileName.Replace(TEXT("//"), TEXT("/")); UE_LOG(LogTemp, Log, TEXT("Path to load object:%s"), *NewFileName); // Save resource path to array FoundObjects.AddUnique(FSoftObjectPath(NewFileName).ResolveObject()); // Loaded Object UObject* LoadedObj;// = StaticLoadObject(UObject::StaticClass(), nullptr, *NewFileName); if (StaticLoadObject(UObject::StaticClass(), nullptr, *NewFileName)) { LoadedObj = StaticLoadObject(UObject::StaticClass(), nullptr, *NewFileName); } else { LoadedObj = nullptr; } if (!LoadedObj) return; UStaticMesh* SM = Cast(LoadedObj); if (SM) { AStaticMeshActor* MeshActor = GetWorld()->SpawnActor(AStaticMeshActor::StaticClass(), FVector(0,0,460), FRotator(0,0,0) ); MeshActor->Rename(*SM->GetName()); MeshActor->SetMobility(EComponentMobility::Movable); MeshActor->GetStaticMeshComponent()->SetStaticMesh(SM); AGetPakAsset::PrintToScreen(TEXT("StaticMesh load successful!"), 5.0f, FColor::White); TestLoadStaticMesh.Add(SM); LoadStaticMeshActors.Add(MeshActor); // UE_LOG(LogTemp, Log, TEXT("StaticMesh load successful!")); } } } } } FPlatformFileManager::Get().SetPlatformFile(*OldPlatform); } void AGetPakAsset::GetAllFilesInPak(FPakFile& PakFile, const FString& InPath, TArray& OutFiles) { // Retrieve files in the current path TArray FoundFileNames; PakFile.FindPrunedFilesAtPath(FoundFileNames, *InPath, true, false, false); for (const FString& Filename : FoundFileNames) { // Add the current file to the list OutFiles.Add(Filename); } // Retrieve subdirectories under the current path TArray Subdirectories; PakFile.FindPrunedFilesAtPath(Subdirectories, *InPath, false, true, false); // Retrieve directory path, do not retrieve files // Traverse subdirectories and recursively call VNet Files InPak for (const FString& Subdirectory : Subdirectories) { // Recursive call to retrieve all files in the subdirectories GetAllFilesInPak(PakFile, Subdirectory, OutFiles); } } void AGetPakAsset::PrintToScreen(const FString& Message, float Duration = 5.0f, FColor Color = FColor::Blue) { if (GEngine) { GEngine->AddOnScreenDebugMessage(-1, Duration, Color, Message); } } void AGetPakAsset::UnloadAsset() { if (PakPlatform.IsValid() && PakFileFullPath != TEXT("")) { for (int i = 0; i < LoadStaticMeshActors.Num(); i++) { if (!LoadStaticMeshActors[i]) continue; LoadStaticMeshActors[i]->Destroy(); LoadStaticMeshActors[i]->ConditionalBeginDestroy(); // Forced release of resources } LoadStaticMeshActors.Empty(); PakFileFullPath.Empty(); // Ensure all references are released FlushAsyncLoading(); CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS); PakPlatform->Unmount(*PakFileFullPath); PakPlatform.Reset();// Release PakPlatform resources // Remove registered mount points FPackageName::UnRegisterMountPoint(RootPath, ContentPath); // Forcefully release PakPrecacher // extern FPakPreca } } void AGetPakAsset::UnloadPakFile() { // Stop all asynchronous records FlushNetDormancy(); GEngine->ForceGarbageCollection(true); // Uninstall the mounted Pak if (PakPlatform.IsValid() && !PakFileFullPath.IsEmpty()) { PakPlatform->Unmount(*PakFileFullPath); } // Release PakPlatform resources PakPlatform.Reset(); // Remove registered mount points FPackageName::UnRegisterMountPoint(RootPath, ContentPath); // Restore original platform files FPlatformFileManager::Get().SetPlatformFile(*OldPlatform); } [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79589801/regarding-the-error-issue-of-repeatedly-loading-and-unloading-pak-files-during-p[/url]