可以把一些非 UE 资源文件(比如 txt,视频)等文件打包到 Pak 中,在游戏运行中访问,可以使用我上面写的 HotPatcher 工具来打包,这里写一下在运行时访问的方法。
首先将文件打包到 Pak:
这里我是将文件 AAAAA.json
打包到了 Pak 中,其挂载路径为../../../PROJECT_NAME/AAAAA.json
.
在游戏中访问一定要使用挂载路径,可以使用 FPaths::ProjectDir
在打包后获取到的是相对路径,在 PIE 下是项目的相对路径。
使用方法:
其中的 PeojectDir
是FPaths::ProjectDir
,LoadFileToString
则是 IFileManager::LoadFileToString
的封装。
运行结果:
如果想要访问打包出的项目文件和挂载的 Pak 中的文件,可以使用下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void UPakVisitorHelper::VisitorProjectDir() { IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
FFillArrayDirectoryVisitor Visitor; PlatformFile.IterateDirectory(*FPaths::ProjectDir(), Visitor);
UE_LOG(LogTemp,Log,TEXT("Found Files:")); for (const auto& File : Visitor.Files) { UE_LOG(LogTemp, Log, TEXT("%s"), *File); } UE_LOG(LogTemp, Log, TEXT("Found Directorys:")); for (const auto& Dir : Visitor.Directories) { UE_LOG(LogTemp, Log, TEXT("%s"), *Dir); } }
|
IPlatformFile::IterateDirectory
这个函数有两个原型:
1 2
| virtual bool IterateDirectory(const TCHAR * Directory, FDirectoryVisitor Visitor); virtual bool IterateDirectory(const TCHAR * Directory,FDirectoryVisitorFunc Visitor);
|
可以传入一个继承自 FDirectoryVisitor
的对象,或者传入一个下列签名的函数对象:
1
| typedef TFunctionRef < bool(const TCHAR *, bool)> FDirectoryVisitorFunc
|
支持传入一个 Lambda 也是可以的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| TArray<FString> Files; TArray<FString> Dirs;
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); auto FallArrayDirVisitor = [&Files,&Dirs](const TCHAR* InItem,bool bInDir)->bool { if (bInDir) { Dirs.AddUnique(InItem); } else { Files.AddUnique(InItem); } return true; }; PlatformFile.IterateDirectory(*InRelativePath, FallArrayDirVisitor);
|
执行结果:
AssetRegistry.bin
/*.uproject
等文件都是在打包的时候打包进 pak 里的,AAAAA.json
则是上面手动打到 Patch 的 Pak 里的。