UE4.26 PAK hot update (dynamic loading of external resources)

Pack PAK

Packing the PAK needs to use the tools that come with UE4 UnrealPak, and the tool path is in \Epic Games\UE_4.26\Engine\Binaries\Win64.
Terminal cd to this path, enter the following command to datapackage all the resources in the directory intoa.pak

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

code part

First, modify build.cs and add in PublicDependencyModuleNamesPakFile

Next, the code mounts and loads the pak
file.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));
    }
}

After completing this step, you can see your resources under the Engine directory.

At this point, you can use these resources like you usually create resources, and you can fill them in here if you have time.

Guess you like

Origin blog.csdn.net/killfunst/article/details/119680401