UE4 Pak加载
https://blog.csdn.net/u011047958/article/details/78439340
https://blog.csdn.net/u011047958/article/details/78539991
Overview:
本篇主要说明两点内容:一,Pak正确加载的源码内容及遇到的bug所在;二,Pak的生成问题。如果你看到此篇,说明你有可能需要这些文档:
风蚀之月的UnrealPak使用笔记:http://blog.ch-wind.com/unrealpak-note/
UE4 PAK加载资源:http://blog.csdn.net/u014532636/article/details/72844367
https://answers.unrealengine.com/questions/389842/loadpackageasync-always-fails-if-file-string-not-c.html/该篇主要使用了后两篇的内容,第一篇有关于UnrealPak的内容,这个暂时还没有去实践,只是觉得不错就贴出来了。
补充说明:本篇文档使用的当前引擎为:Unreal 4.17.2(有可能由于版本的变更,导致一些API,方法的不适用)。
Required Knowledge:
之前,你需要知道怎么得到Pak,以及它的基本使用方法,最基本的要求是你要知道它是什么。你需要知道加载Pak文件的核心API,头文件,组件内容,这些可以在引擎的文档里查到。
Example Code and Knowledge:
FString SaveContentDir =GetGameContentPakDir() + TEXT("hotupdate.pak");
IPlatformFile&PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
FPakPlatformFile*PakPlatformFile = new FPakPlatformFile();
PakPlatformFile->Initialize(&PlatformFile,TEXT(""));
FPlatformFileManager::Get().SetPlatformFile(*PakPlatformFile);
FPakFilePakFile(&PlatformFile,*SaveContentDir, false);
FStringMountPoint(FPaths::GameContentDir());
PakFile.SetMountPoint(*MountPoint);
if(PakPlatformFile->Mount(*SaveContentDir, 0, *MountPoint))
{
TArray<FString> FileList;
PakFile.FindFilesAtPath(FileList, *PakFile.GetMountPoint(), true,false, true);
FStreamableManager StreamableManager;
AssetName = "/Game/Paks/MeshCar.MeshCar";
FStringAssetReference reference = AssetName;
UObject* LoadObject = StreamableManager.SynchronousLoad(reference);
If(LoadObject!=nullptr)
{
UStaticMesh* Obj = Cast<UStaticMesh>(LoadObject);
If(Obj!=nullptr)
{
AStaticMeshActor*actor=GetWorld()->SpawnActor<AStaticMeshActor>
(FVector::ZeroVector, FRotator::ZeroRotator);
actor->GetStaticMeshComponent()->Mobility= EComponentMobility::Movable;
actor->GetStaticMeshComponent()->SetStaticMesh(Obj);
}
else
{
….
}
}
}
这些代码是从Overview提及的第二篇链接文章改编而来的,可能是由于版本的原因,该博主的文章,并没有正常发挥作用,把资源加载出来。于是中间经历了大量的尝试,其中值得一提的是用到了下面的代码,不过没来的及试,如果可以的话,你可以代为尝试:
if (FCoreDelegates::OnMountPak.IsBound())
{
//4.17版本下Execute(FilePath,4),并不能使用,新的的API多出了一个参数,我就随意添加了一个nullptr,如果你有时间可以细看一下
FCoreDelegates::OnMountPak.Execute(FilePath,4,nullptr);
GEngine->AddOnScreenDebugMessage(-1,5.f, FColor::Cyan, FilePath);
}
转到正题,关于修改的内容:
SaveContentDir路径内容,我是使用了自己存放Pak的文件夹也就是../../../[Project_Name]/
Content/Paks/, GetGameContentPakDir(),下封装了UE4的获取游戏内容的路径,以进行支持IOS的路径安排,事实上,没有进行路径转换,Pak在IOS上也能正确的读取,一种猜测是和UE4自己的封装有关。
FString GetGameContentPakDir()
{
returnFPaths::GameContentDir()+”Paks/”;
}
当然,你也可把自己的Pak的文件名,作为参数的方式传入
Mount的路径也换成了FPaths::GameContentDir();
关于资源的异步加载:
AssetName = "/Game/Paks/MeshCar";
FStringAssetReference reference = AssetName;
UObject* LoadObject = StreamableManager.SynchronousLoad(reference);
这个和博主的做法类似,但使用博主的路径方式,并不能正确加载出内容,于是有了第三篇unreal answer的sonical1978一句话,是一个亮点:” 通常pak是很容易加载成功的,而异步读取资源是否成功取决于你读取的路径是否正确。把那些.../../../..全部删掉,之后就可以在资源注册表通过各种方法使用这些资源了”,事实上亦是如此,路径问题始终是困扰本人的问题所在,于是,在这个地方,对这个原博主的代码内容,进行更改,直接对使用的资源进行加载即“/Game/Paks/MeshCar”这是个UStaticMesh,所以为了验证是否加载成功,把它加载到了世界场景中:
UStaticMesh* Obj = Cast<UStaticMesh>(LoadObject);
If(Obj!=nullptr)
{
AStaticMeshActor*actor=GetWorld()->SpawnActor<AStaticMeshActor>
(FVector::ZeroVector, FRotator::ZeroRotator);
actor->GetStaticMeshComponent()->Mobility= EComponentMobility::Movable;
actor->GetStaticMeshComponent()->SetStaticMesh(Obj);
}
最终,你会看到指定的模型被加载进场景中。
PS:刚接触的时候,对Pak有一个误解,在之前的测试中,一个朋友提供的文档中,关于Patch的内容误导了一下,到后来才知道,怎样获取正确的更新,Pak需要指定cook内容才能得到合理的利用,通过项目打包指定的map,只有在map中放置的资源才能被加载,而那些资源之外的内容,很有可能在资源注册列表中找不到
————————————————
版权声明:本文为CSDN博主「bluecoder66」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011047958/article/details/78539991