UE挂载Pak的调研心得

 前段时间,由于工作需要,研究了一下如何挂载Pak以及在热更应用中的思考,包括新增的Pak和替换旧Pak。在查阅大量资料和亲手实践后,在此做个总结记录。

前置知识

Pak的概念、制作、挂载等前置知识,可以查看下列参考文档:

聊一聊UE4中的pak - 弘竣的文章 - 知乎

Pak文件的优先级

  1. 挂载的顺序并不是查找的顺序,每当有新文件挂载时,内部的pak列表会根据优先级来排序。优先级大的排在前面,优先被查找。
  2. 优先级规则

        i.规则1:基于文件路径

                "[ProjectName]/Content/Paks/[ProjectName]-XXX"的pak文件优先级为4

                "[ProjectName]/Content/Paks" 目录下除上述pak文件的优先级为3

                "Engine/Content/Paks"目录优先级为2

                "[ProjectName]/Saved/Paks" 目录优先级为1

                其余为0

        ii.规则2:基于文件名

                文件名以"_P.pak"结尾的Pak享有额外的优先级,最低为100。

                “_n_P.pak”结尾的优先级 =(n+1)*100+规则1 的优先级

        iii.规则3:手动挂载Pak时可以指定优先级

挂载Pak

  • 挂载,只是读取pak中的文件列表信息。加载时会按照Pak优先级去查找文件。

注意:要在挂载完所需Pak之后,再加载所需资源。例如:pak1.pak里有一个蓝图Actor,pak2.pak里是稍作修改的Actor。如果挂载pak1.pak,加载Actor,再挂载pak2.pak,再加载Actor,这种顺序就只能加载到pak1中的Actor

  • 引擎会自动从以下三个目录挂载Pak:

        [ProjectName]/Content/Paks

        [ProjectName]/Saved/Paks

        Engine/Content/Paks

1.挂载新增的Pak

方法1:将Pak放到引擎自动挂载的目录下(若开启IO,需要包含.pak/.utoc/.ucas

三个文件)。如果是用UnrealPak打的Pak包,需要将挂载点一起打进包里,才能在自动挂载后正确加载包里的资源。

方法2:手动挂载

2.挂载新Pak,替换旧Pak

方法1:直接替换掉旧Pak文件。若开启IO,需要将.pak/.utoc/.ucas一起替换。

方法2:将Pak放到引擎自动挂载的目录下,并根据优先级规则调整文件名来使优先级高于旧Pak。同样需注意Pak包里包含正确挂载点。若开启IO,需要将.pak/.utoc/.ucas一起重命名。

方法3:手动挂载

3.手动挂载Pak

3.1注意事项:
  • 打包模式使用 Cooked 过的 Pak
  • PIE 模式使用未 Cooked 过的 Pak
  • 打包模式,MountPoint 使用相对路径,即../../../[项目名]/Content/[子目录名]
  • PIE模式,MountPoint 使用绝对路径,即FPaths::ProjectContentDir() + TEXT("[Content后的子目录]/")
  • 需要切换到Pak平台下,才能加载Pak包中的资源
  • Cook路径和挂载点路径尽量保持一致,否则容易导致依赖丢失
  • 若开启IO,需要将.pak/.utoc/.ucas放在相同目录下,只有.pak是无法正确挂载的。
  • 可以挂载与包里同名的Pak
3.2核心代码示例

示例情境:

  1. 工程E:\UE5Projects\PakDemo\Content\Pak1下有一个蓝图Actor1,且关闭IO。
  2. Cook后,使用UnrealPak将E:\UE5Projects\PakDemo\Saved\Cooked\Windows\PakDemo\Content\Pak1下的资源打包到G:\Actor1.pak。
  3. 通过代码手动挂载Actor1.pak,加载蓝图Actor1并创建实例
  4. //.Build.cs 添加 PakFile 模块
    //获取当前使用的平台
    InnerPlatformFile = &FPlatformFileManager::Get().GetPlatformFile();
    InnerPlatformFile->GetName());	
    //初始化PakPlatformFile
    PakPlatformFile = MakeShareable(new FPakPlatformFile());
    PakPlatformFile.Get()->Initialize(InnerPlatformFile, TEXT(""));
    // 切换到Pak平台
    FPlatformFileManager::Get().SetPlatformFile(*PakPlatformFile.Get());
    // 获取Pak文件(PakPath = “G:\Actor1.pak” )
    TRefCountPtr<FPakFile> PakFile = new FPakFile(InnerPlatformFile, *PakPath, false);
    FString MountPoint = PakFile->GetMountPoint();
    //按需调整挂载点,若Pak包里包含正确挂载点,则无需调整
    //PIE模式
    //MountPoint = FPaths::ProjectContentDir() + TEXT("Pak1/");
    //打包模式
    MountPoint = TEXT("../../../PakDemo/Content/Park1");
    //对pak文件进行挂载
    //100000为优先级
    //若Pak包里自带正确挂载点,*MountPoint可不传
    if (PakPlatformFile->Mount(*PakPath, 100000, *MountPoint))
    {
        //加载Actor1并创建实例
        UClass* BP_PakTestClass = LoadClass<AActor>(nullptr,TEXT("Blueprint'/Game/Pak1/Actor1.Actor1_C'"));
        if (BP_PakTestClass) 
        {
            GetWorld()->SpawnActor<AActor>(BP_PakTestClass,
            FVector::ZeroVector,FRotator::ZeroRotator);
        }
    }
    

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值