runtime load final
This commit is contained in:
parent
449d943948
commit
cc5a0b3c4e
@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
[/Script/EngineSettings.GameMapsSettings]
|
||||
GameDefaultMap=/Engine/Maps/Templates/OpenWorld
|
||||
GameDefaultMap=/Game/Levels/Test/L_Test.L_Test
|
||||
EditorStartupMap=/Game/Levels/Test/L_Test.L_Test
|
||||
bUseSplitscreen=False
|
||||
GlobalDefaultGameMode=/Game/Blueprints/GameModes/BP_MainGameMode.BP_MainGameMode_C
|
||||
|
Binary file not shown.
Binary file not shown.
BIN
Content/Misc/ImportTest/BP_ImportTest_Barrel.uasset
Normal file
BIN
Content/Misc/ImportTest/BP_ImportTest_Barrel.uasset
Normal file
Binary file not shown.
@ -5,210 +5,117 @@
|
||||
|
||||
#include "IPlatformFilePak.h"
|
||||
|
||||
#include "UObject/Class.h"
|
||||
#include "UObject/UObjectIterator.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr auto mountPath = TEXT("/Game/LoadedContent");
|
||||
}
|
||||
|
||||
UClass* UContentLoader::MountAndRegisterPak(FString pakFilePath)
|
||||
{
|
||||
if(pakFilePath.IsEmpty())
|
||||
return nullptr;
|
||||
|
||||
pakFilePath = FPaths::ProjectContentDir() / pakFilePath;
|
||||
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("ContentLoader: Starting to mount pak: %s"), *pakFilePath));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Starting to mount pak: %s"), *pakFilePath);
|
||||
|
||||
if(!MountPak(*pakFilePath))
|
||||
return nullptr;
|
||||
|
||||
TArray<FString> content;
|
||||
FString mountPoint = GetPakMountContentPath(pakFilePath, content);
|
||||
RegisterMountPoint(mountPath, mountPoint);
|
||||
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("ContentLoader: Pak '%s' contains %d items"), *FPaths::GetCleanFilename(pakFilePath), content.Num()));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Pak '%s' contains %d items"), *FPaths::GetCleanFilename(pakFilePath), content.Num());
|
||||
|
||||
for(auto& i : content)
|
||||
{
|
||||
if(FPaths::GetCleanFilename(i).StartsWith(TEXT("BP_")))
|
||||
{
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, FString::Printf(TEXT("ContentLoader: Found BP class: '%s'"), *i));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Found BP class: '%s'"), *i);
|
||||
return LoadPakObjClassReference(i);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UContentLoader::BeginDestroy()
|
||||
{
|
||||
if(mountedFiles.Num() > 0)
|
||||
{
|
||||
while(mountedFiles.Num() > 0)
|
||||
UnmountPak(*mountedFiles.begin());
|
||||
|
||||
FPlatformFileManager::Get().RemovePlatformFile(GetPakPlatformFile());
|
||||
}
|
||||
//if(mountedFiles.Num() > 0)
|
||||
//{
|
||||
// while(mountedFiles.Num() > 0)
|
||||
// UnmountPak(*mountedFiles.begin());
|
||||
//
|
||||
// FPlatformFileManager::Get().RemovePlatformFile(GetPakPlatformFile());
|
||||
//}
|
||||
|
||||
UObject::BeginDestroy();
|
||||
}
|
||||
|
||||
FPakPlatformFile* UContentLoader::GetPakPlatformFile()
|
||||
UClass* UContentLoader::LoadPak(const FString& pakFilePath)
|
||||
{
|
||||
FPakPlatformFile* pakPlatformFile = nullptr;
|
||||
|
||||
IPlatformFile& platformFile = FPlatformFileManager::Get().GetPlatformFile();
|
||||
if(!platformFile.GetLowerLevel())
|
||||
{
|
||||
pakPlatformFile = new FPakPlatformFile();
|
||||
pakPlatformFile->Initialize(&platformFile, TEXT(""));
|
||||
FPlatformFileManager::Get().SetPlatformFile(*pakPlatformFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
pakPlatformFile = (FPakPlatformFile*)(FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile")));
|
||||
}
|
||||
|
||||
if(!pakPlatformFile)
|
||||
{
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("ContentLoader: PakFileManager not found"));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: PakFileManager not found"));
|
||||
}
|
||||
|
||||
return pakPlatformFile;
|
||||
}
|
||||
|
||||
bool UContentLoader::MountPak(const FString& path)
|
||||
{
|
||||
FPakPlatformFile* pakFileMgr = GetPakPlatformFile();
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Starting to mount pak %s"), *pakFilePath);
|
||||
|
||||
FPakPlatformFile* pakFileMgr = (FPakPlatformFile*)(FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile")));
|
||||
if(!pakFileMgr)
|
||||
return false;
|
||||
|
||||
FString mountPoint = FString::Printf(TEXT("%s/%s"), mountPath, *FPaths::GetBaseFilename(*path));
|
||||
bool mounted = pakFileMgr->Mount(*path, 0, *mountPoint);
|
||||
if(!mounted)
|
||||
{
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("ContentLoader: Pak %s mount failed"), *FPaths::GetCleanFilename(path)));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Pak %s mount failed"), *FPaths::GetCleanFilename(path));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, FString::Printf(TEXT("ContentLoader: Pak %s mounted at %s"), *FPaths::GetCleanFilename(path), *mountPoint));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Pak %s mounted at %s"), *FPaths::GetCleanFilename(path), *mountPoint);
|
||||
|
||||
mountedLock.Lock();
|
||||
mountedFiles.Add(path);
|
||||
mountedLock.Unlock();
|
||||
UE_LOG(LogTemp, Warning, TEXT("ContentLoader: Unable to get PakPlatformFile."));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool UContentLoader::UnmountPak(const FString& path)
|
||||
if(!pakFileMgr->Mount(*pakFilePath, 0))
|
||||
{
|
||||
FPakPlatformFile* pakFileMgr = GetPakPlatformFile();
|
||||
|
||||
if(!pakFileMgr)
|
||||
return false;
|
||||
|
||||
bool unmounted = pakFileMgr->Unmount(*path);
|
||||
if(!unmounted)
|
||||
{
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("ContentLoader: Pak %s unmount failed"), *FPaths::GetCleanFilename(path)));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Pak %s unmount failed"), *FPaths::GetCleanFilename(path));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Green, FString::Printf(TEXT("ContentLoader: Pak %s unmounted successfully"), *FPaths::GetCleanFilename(path)));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Pak %s unmounted successfully"), *FPaths::GetCleanFilename(path));
|
||||
|
||||
mountedLock.Lock();
|
||||
mountedFiles.Remove(path);
|
||||
mountedLock.Unlock();
|
||||
UE_LOG(LogTemp, Warning, TEXT("ContentLoader: Unable to mount pak %s."), *pakFilePath);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
UE_LOG(LogTemp, Warning, TEXT("ContentLoader: Pak %s mounted successfully."), *pakFilePath);
|
||||
|
||||
TArray<FString> content;
|
||||
const FString mountPoint = GetPakMountContent(pakFilePath, &content);
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Pak '%s' contains %d items."), *FPaths::GetCleanFilename(pakFilePath), content.Num());
|
||||
|
||||
FPackageName::RegisterMountPoint("/Game/", mountPoint);
|
||||
for(auto& i : content)
|
||||
{
|
||||
if(FPaths::GetCleanFilename(i).StartsWith(TEXT("BP_")))
|
||||
{
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Found BP class '%s' of pak %s."), *i, *pakFilePath);
|
||||
return GetPakClass(i);
|
||||
}
|
||||
}
|
||||
|
||||
void UContentLoader::RegisterMountPoint(const FString& rootPath, const FString& contentPath)
|
||||
{
|
||||
FPackageName::RegisterMountPoint(rootPath, contentPath);
|
||||
}
|
||||
void UContentLoader::UnRegisterMountPoint(const FString& rootPath, const FString& contentPath)
|
||||
{
|
||||
FPackageName::UnRegisterMountPoint(rootPath, contentPath);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FString UContentLoader::GetPakMountPoint(const FString& pakFilePath)
|
||||
FString UContentLoader::GetPakMountContent(const FString& pakFilePath, TArray<FString>* content)
|
||||
{
|
||||
TArray<FString> contentProxy;
|
||||
if(!content)
|
||||
content = &contentProxy;
|
||||
|
||||
FString mountPoint, contentPath, contentPathTail;
|
||||
TRefCountPtr<FPakFile> pakFile = new FPakFile(FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile")), *pakFilePath, false);
|
||||
|
||||
auto pak = pakFile.GetReference();
|
||||
if(pakFile.GetReference()->IsValid())
|
||||
{
|
||||
return pakFile.GetReference()->GetMountPoint();
|
||||
mountPoint = pakFile.GetReference()->GetMountPoint();
|
||||
mountPoint.Split("/Content/", &contentPath, &contentPathTail);
|
||||
|
||||
for(FPakFile::FFilenameIterator It(*pakFile.GetReference(), false); It; ++It)
|
||||
if(FPaths::GetExtension(It.Filename()) == TEXT("uasset"))
|
||||
content->Add(FString::Printf(TEXT("%s%s"), *contentPathTail, *It.Filename()));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
TArray<FString> UContentLoader::GetPakContent(const FString& pakFilePath, const FString& appendPath)
|
||||
if(!contentPath.IsEmpty())
|
||||
{
|
||||
TRefCountPtr<FPakFile> pakFile = new FPakFile(FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile")), *pakFilePath, false);
|
||||
TArray<FString> pakContent;
|
||||
|
||||
if(pakFile.GetReference()->IsValid())
|
||||
{
|
||||
for(FPakFile::FFilenameIterator it{ *pakFile, false }; it; ++it)
|
||||
{
|
||||
if(FPaths::GetExtension(it.Filename()) == TEXT("uasset"))
|
||||
{
|
||||
pakContent.Add(FString::Printf(TEXT("%s%s"), *appendPath, *it.Filename()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return pakContent;
|
||||
}
|
||||
|
||||
FString UContentLoader::GetPakMountContentPath(const FString& pakFilePath, TArray<FString>& content)
|
||||
{
|
||||
FString contentPath, appendPath;
|
||||
FString mountPoint = GetPakMountPoint(pakFilePath);
|
||||
|
||||
if(mountPoint.Split("/Content/", &contentPath, &appendPath))
|
||||
{
|
||||
content = GetPakContent(pakFilePath, appendPath);
|
||||
return FString::Printf(TEXT("%s/Content/"), *contentPath);
|
||||
}
|
||||
else
|
||||
else if(content->Num())
|
||||
{
|
||||
content = GetPakContent(pakFilePath, appendPath);
|
||||
if(content.Num() > 0)
|
||||
{
|
||||
mountPoint = FString::Printf(TEXT("%s%s"), *mountPoint, *content[0]);
|
||||
if(mountPoint.Split("/Content/", &contentPath, &appendPath))
|
||||
const FString fullPath = FString::Printf(TEXT("%s%s"), *mountPoint, *((*content)[0]));
|
||||
if(fullPath.Split("/Content/", &contentPath, &contentPathTail))
|
||||
{
|
||||
return FString::Printf(TEXT("%s/Content/"), *contentPath);
|
||||
}
|
||||
}
|
||||
|
||||
return FString("");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
UClass* UContentLoader::LoadPakObjClassReference(const FString& pakContentPath)
|
||||
UClass* UContentLoader::GetPakClass(const FString& pakContentPath)
|
||||
{
|
||||
FString assetName = FString::Printf(TEXT("%s/%s.%s_C"), mountPath, *FPaths::GetBaseFilename(pakContentPath, false), *FPaths::GetBaseFilename(pakContentPath, true));
|
||||
|
||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("ContentLoader: Loading '%s' class"), *assetName));
|
||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Loading '%s' class"), *assetName);
|
||||
|
||||
return nullptr;//StaticLoadClass(UObject::StaticClass(), nullptr, *assetName);
|
||||
const FString assetName = FString::Printf(TEXT("/Game/%s.%s"), *FPaths::GetBaseFilename(pakContentPath, false), *FPaths::GetBaseFilename(pakContentPath, true));
|
||||
const FString className = assetName + TEXT(".") + FPackageName::GetShortName(assetName) + TEXT("_C");
|
||||
auto result = StaticLoadClass(UObject::StaticClass(), nullptr, *className);
|
||||
if(!result)
|
||||
UE_LOG(LogTemp, Warning, TEXT("ContentLoader: Unable to load pak class: %s."), *className);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool UContentLoader::UnloadPak(const FString& pakFilePath)
|
||||
{
|
||||
FPakPlatformFile* pakFileMgr = (FPakPlatformFile*)(FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile")));
|
||||
if(!pakFileMgr)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("Unable to get PakPlatformFile for pak file (Unmount): %s"), *pakFilePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!pakFileMgr->Unmount(*pakFilePath))
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("Unable to unmount pak: %s"), *pakFilePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
const FString mountPoint = GetPakMountContent(pakFilePath);
|
||||
FPackageName::UnRegisterMountPoint("/Game/", mountPoint);
|
||||
|
||||
return true;
|
||||
}
|
@ -13,27 +13,15 @@ class UContentLoader : public UObject
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = "ContentLoader")
|
||||
UClass* MountAndRegisterPak(FString pakFilePath);
|
||||
|
||||
|
||||
UClass* LoadPak(const FString& pakFilePath);
|
||||
|
||||
protected:
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
class FPakPlatformFile* GetPakPlatformFile();
|
||||
UFUNCTION(BlueprintCallable, Category = "ContentLoader")
|
||||
bool UnloadPak(const FString& pakFilePath);
|
||||
|
||||
bool MountPak(const FString& path);
|
||||
bool UnmountPak(const FString& path);
|
||||
|
||||
void RegisterMountPoint(const FString& rootPath, const FString& contentPath);
|
||||
void UnRegisterMountPoint(const FString& rootPath, const FString& contentPath);
|
||||
|
||||
FString GetPakMountPoint(const FString& pakFilePath);
|
||||
TArray<FString> GetPakContent(const FString& pakFilePath, const FString& appendPath);
|
||||
FString GetPakMountContentPath(const FString& pakFilePath, TArray<FString>& content);
|
||||
|
||||
UClass* LoadPakObjClassReference(const FString& pakContentPath);
|
||||
|
||||
TSet<FString> mountedFiles;
|
||||
FCriticalSection mountedLock;
|
||||
protected:
|
||||
FString GetPakMountContent(const FString& pakFilePath, TArray<FString>* content = nullptr);
|
||||
UClass* GetPakClass(const FString& pakContentPath);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user