UE4.26 PAK热更新(动态加载外部资源)

打包PAK

打包PAK需要用到UE4自带的UnrealPak工具,工具路径在\Epic Games\UE_4.26\Engine\Binaries\Win64
终端cd到该路径,输入以下命令就可以把data目录下所有资源打包成a.pak

>UnrealPak a.pak -create=d:\data

代码部分

首先,修改build.cs, 在PublicDependencyModuleNames中添加PakFile

接着,代码里挂载和加载pak文件
.h

TArray<FSoftObjectPath> objectPaths;
TArray<TSoftObjectPtr<UObject>> objectPtrs;

.cpp

void xxx::MountPak()
{
    
    
    //第一步
    //FPlatformFileManager::Get()返回单例
    //GetPlatformFile()返回相应平台的PlatformFile,即处理相应平台文件读写的对象
    //因此在Windows平台,这里返回的是FWindowsPlatformFile的实例
    IPlatformFile& InnerPlatform = FPlatformFileManager::Get().GetPlatformFile();
 
    //第二步
    //这里创建了一个FPakPlatformFile,但是未指定当前使用什么平台去读写这个文件
    FPakPlatformFile* PakPlatformFile = new FPakPlatformFile();
 
    //第三步
    //使用相应平台的PlatformFile去初始化PakPlatformFile
    //第二个参数是命令行参数,一般都为空
    PakPlatformFile->Initialize(&InnerPlatform, TEXT(""));
 
    //第四步
    //再将当前PlatformFile设置为"相应平台下pak文件读写"的模式
    FPlatformFileManager::Get().SetPlatformFile(*PakPlatformFile);
 
    const FString PakFileFullName = TEXT("D:/data/a.pak");
 
    //测试用MountPoint,我在PIE模式测试过Game路径不行
    FString MountPoint("/Engine/");
 
    //创建FPakFile对象,同样使用相应平台的PlatformFile初始化
    //第二个参数是pak文件的完整路径+名称
    //第三个参数是是否有符号?
    FPakFile* Pak = new FPakFile(&InnerPlatform, *PakFileFullName, false);
 
    if (Pak->IsValid())
    {
    
    
        //具体Mount方法可以参考函数 FPakPlatformFile::Mount
        //但是其中有大量多余内容(例如版本编号处理)
        //Pak->SetMountPoint(*MountPoint);
 
        PakPlatformFile->Mount(*PakFileFullName,1000,*MountPoint);
 
        TArray<FString> Files;
        Pak->FindFilesAtPath(Files, *(Pak->GetMountPoint()), true, false, true);
 
        for(auto File : Files)
        {
    
    
            FString Filename, FileExtn;
            int32 LastSlashIndex;
            File.FindLastChar(*TEXT("/"), LastSlashIndex);
            FString FileOnly = File.RightChop(LastSlashIndex + 1); 
            FileOnly.Split(TEXT("."), &Filename, &FileExtn);
 
            if (FileExtn == TEXT("uasset"))
            {
    
    
                File = FileOnly.Replace(TEXT("uasset"), *Filename);
                File = TEXT("/Engine/")+File;
                objectPaths.AddUnique(FSoftObjectPath(File));
                
                //将FSoftObjectPath直接转换为TSoftObjectPtr<UObject>并储存
                objectPtrs.AddUnique(TSoftObjectPtr<UObject>(objectPaths[objectPaths.Num()-1]));
            }
            
        }
        UAssetManager::GetStreamableManager().RequestAsyncLoad(objectPaths,FStreamableDelegate::CreateUObject(this,&ATestDialogGameModeBase::CreateAllChildren));
    }
}

完成这一步之后,可以在Engine目录下看到你的资源。

此时就可以像平时创建资源一样使用这些资源了,这里有空可以补上。

猜你喜欢

转载自blog.csdn.net/killfunst/article/details/119680401