runtime load final
This commit is contained in:
parent
449d943948
commit
cc5a0b3c4e
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
[/Script/EngineSettings.GameMapsSettings]
|
[/Script/EngineSettings.GameMapsSettings]
|
||||||
GameDefaultMap=/Engine/Maps/Templates/OpenWorld
|
GameDefaultMap=/Game/Levels/Test/L_Test.L_Test
|
||||||
EditorStartupMap=/Game/Levels/Test/L_Test.L_Test
|
EditorStartupMap=/Game/Levels/Test/L_Test.L_Test
|
||||||
bUseSplitscreen=False
|
bUseSplitscreen=False
|
||||||
GlobalDefaultGameMode=/Game/Blueprints/GameModes/BP_MainGameMode.BP_MainGameMode_C
|
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 "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()
|
void UContentLoader::BeginDestroy()
|
||||||
{
|
{
|
||||||
if(mountedFiles.Num() > 0)
|
//if(mountedFiles.Num() > 0)
|
||||||
{
|
//{
|
||||||
while(mountedFiles.Num() > 0)
|
// while(mountedFiles.Num() > 0)
|
||||||
UnmountPak(*mountedFiles.begin());
|
// UnmountPak(*mountedFiles.begin());
|
||||||
|
//
|
||||||
FPlatformFileManager::Get().RemovePlatformFile(GetPakPlatformFile());
|
// FPlatformFileManager::Get().RemovePlatformFile(GetPakPlatformFile());
|
||||||
}
|
//}
|
||||||
|
|
||||||
UObject::BeginDestroy();
|
UObject::BeginDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
FPakPlatformFile* UContentLoader::GetPakPlatformFile()
|
UClass* UContentLoader::LoadPak(const FString& pakFilePath)
|
||||||
{
|
{
|
||||||
FPakPlatformFile* pakPlatformFile = nullptr;
|
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Starting to mount pak %s"), *pakFilePath);
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
|
FPakPlatformFile* pakFileMgr = (FPakPlatformFile*)(FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile")));
|
||||||
if(!pakFileMgr)
|
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, Warning, TEXT("ContentLoader: Unable to get PakPlatformFile."));
|
||||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Pak %s mount failed"), *FPaths::GetCleanFilename(path));
|
return nullptr;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
if(!pakFileMgr->Mount(*pakFilePath, 0))
|
||||||
}
|
|
||||||
bool UContentLoader::UnmountPak(const FString& path)
|
|
||||||
{
|
{
|
||||||
FPakPlatformFile* pakFileMgr = GetPakPlatformFile();
|
UE_LOG(LogTemp, Warning, TEXT("ContentLoader: Unable to mount pak %s."), *pakFilePath);
|
||||||
|
return nullptr;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
return nullptr;
|
||||||
{
|
|
||||||
FPackageName::RegisterMountPoint(rootPath, contentPath);
|
|
||||||
}
|
|
||||||
void UContentLoader::UnRegisterMountPoint(const FString& rootPath, const FString& contentPath)
|
|
||||||
{
|
|
||||||
FPackageName::UnRegisterMountPoint(rootPath, contentPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
TRefCountPtr<FPakFile> pakFile = new FPakFile(FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile")), *pakFilePath, false);
|
||||||
|
auto pak = pakFile.GetReference();
|
||||||
if(pakFile.GetReference()->IsValid())
|
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 {};
|
if(!contentPath.IsEmpty())
|
||||||
}
|
|
||||||
|
|
||||||
TArray<FString> UContentLoader::GetPakContent(const FString& pakFilePath, const FString& appendPath)
|
|
||||||
{
|
{
|
||||||
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);
|
return FString::Printf(TEXT("%s/Content/"), *contentPath);
|
||||||
}
|
}
|
||||||
else
|
else if(content->Num())
|
||||||
{
|
{
|
||||||
content = GetPakContent(pakFilePath, appendPath);
|
const FString fullPath = FString::Printf(TEXT("%s%s"), *mountPoint, *((*content)[0]));
|
||||||
if(content.Num() > 0)
|
if(fullPath.Split("/Content/", &contentPath, &contentPathTail))
|
||||||
{
|
|
||||||
mountPoint = FString::Printf(TEXT("%s%s"), *mountPoint, *content[0]);
|
|
||||||
if(mountPoint.Split("/Content/", &contentPath, &appendPath))
|
|
||||||
{
|
{
|
||||||
return FString::Printf(TEXT("%s/Content/"), *contentPath);
|
return FString::Printf(TEXT("%s/Content/"), *contentPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FString("");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
UClass* UContentLoader::GetPakClass(const FString& pakContentPath)
|
||||||
}
|
|
||||||
|
|
||||||
UClass* UContentLoader::LoadPakObjClassReference(const FString& pakContentPath)
|
|
||||||
{
|
{
|
||||||
FString assetName = FString::Printf(TEXT("%s/%s.%s_C"), mountPath, *FPaths::GetBaseFilename(pakContentPath, false), *FPaths::GetBaseFilename(pakContentPath, true));
|
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");
|
||||||
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("ContentLoader: Loading '%s' class"), *assetName));
|
auto result = StaticLoadClass(UObject::StaticClass(), nullptr, *className);
|
||||||
UE_LOG(LogTemp, Log, TEXT("ContentLoader: Loading '%s' class"), *assetName);
|
if(!result)
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("ContentLoader: Unable to load pak class: %s."), *className);
|
||||||
return nullptr;//StaticLoadClass(UObject::StaticClass(), nullptr, *assetName);
|
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:
|
public:
|
||||||
UFUNCTION(BlueprintCallable, Category = "ContentLoader")
|
UFUNCTION(BlueprintCallable, Category = "ContentLoader")
|
||||||
UClass* MountAndRegisterPak(FString pakFilePath);
|
UClass* LoadPak(const FString& pakFilePath);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void BeginDestroy() override;
|
virtual void BeginDestroy() override;
|
||||||
|
|
||||||
class FPakPlatformFile* GetPakPlatformFile();
|
UFUNCTION(BlueprintCallable, Category = "ContentLoader")
|
||||||
|
bool UnloadPak(const FString& pakFilePath);
|
||||||
|
|
||||||
bool MountPak(const FString& path);
|
protected:
|
||||||
bool UnmountPak(const FString& path);
|
FString GetPakMountContent(const FString& pakFilePath, TArray<FString>* content = nullptr);
|
||||||
|
UClass* GetPakClass(const FString& pakContentPath);
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user