博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UE4 Pak加载
阅读量:20799 次
发布时间:2019-12-03

本文共 3157 字,大约阅读时间需要 10 分钟。

Overview:

   本篇主要说明两点内容:一,Pak正确加载的源码内容及遇到的bug所在;二,Pak的生成问题。如果你看到此篇,说明你有可能需要这些文档:

风蚀之月的UnrealPak使用笔记:

UE4 PAK加载资源:

该篇主要使用了后两篇的内容,第一篇有关于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中放置的资源才能被加载,而那些资源之外的内容,很有可能在资源注册列表中找不到。

转载地址:http://pkuubk.baihongyu.com/

你可能感兴趣的文章
一个案例教你理解Spring面向切面编程(Spring Aop)
查看>>
手把手教你整合SSM框架
查看>>
自己造个简单数据校验的注解@Value和@Mail
查看>>
Poj百练 4148:生理周期 (分类:枚举)
查看>>
Java如何读写注册表
查看>>
java如何利用模板文件生成word文档
查看>>
java读写xlsx格式的MS Excel文件
查看>>
vue的一些基础知识点
查看>>
webpack错误记录(不定期更新)
查看>>
Poj百练 2692:假币问题 (分类:模拟)
查看>>
SpringBoot实现一个文件上传服务
查看>>
前后分但文件上传与多文件上传,前端实现
查看>>
Poj百练 2711:合唱队形 (分类:动态规划)
查看>>
SpringBoot自定义banner
查看>>
JWT(JSON Web Token)认证小结
查看>>
Poj百练 2746:约瑟夫问题 (分类:模拟)
查看>>
git知识点梳理
查看>>
git中tag标签的用法
查看>>
redis持久化, RBD(Redis Database)和AOF(Append Only File)
查看>>
VTK:文字来源TextOrigin
查看>>