UE4 Pak package hot update

The pak file, also known as the pak package, is a file format used by UE4 to update resources (including hot updates). UE4 merges multiple files into one pak file, and updates resources through the pak file. The pak file can not only load UE4 resource files, such as: uasset, umap, etc., can also load non-resource files, such as: xml, json, txt, etc. In addition to the file pak file, it can also contain some additional information, such as: the encryption of the pak file, the version of the pak etc.

1. Cook resources (baking resources)

1. Why bake resources

Since the program runs on a variety of platforms, and different platforms have their own resource formats, it is necessary to bake the resources of the corresponding platform before creating the Pak file. UE4 provides UE4Editor-Cmd.exe tool to provide resource baking, UE4Editor-Cmd .exe can be commanded directly in cmd.

<引擎路径>\Engine\Binaries\Win64\UE4Editor-Cmd.exe <项目路径>\RobotEngine.uproject -run=Cook  -TargetPlatform=<平台类型> -fileopenlog -unversioned -abslog=<日志输出路径> -stdout -CrashForUAT -unattended -NoLogTimes  -UTF8Output


The baked resources will be stored in <项目文件夹>/Saved/Cooked/<对应的平台名称>/<项目名称>/Content/<对应的目录>the specific meaning of the parameters, which will be left for future research.

2. Platform types supported by baking

UE4's resource baking supports most of the current mainstream platforms:

Of course, if we only need to bake the resources of the Windows platform, UE4 directly provides the bake button

 

Second, pack the Pak file

UE4 provides a tool for creating Pak files—UnrealPak.exe for us to use. We can run UnrealPak.exe directly from the cmd command line to create Pak packages for specified files.

<引擎路径>\Engine\Binaries\Win64\UnrealPak.exe <pak文件路径> -Create=<项目路径>\RobotEngine\Saved\Cooked\Android_ASTC\RobotEngine\Content\Comps\<cook资源文件所在的文件夹> -compress


There are a few points to note here. The pak file path is the path where we want to store the created pak file, such as: D:\PAK\mypak.pak. The folder where the cook resource file is located is the directory where the uasset file is located after cooking. Remember not File path, because the directory can contain multiple resource files, among which Andriod_ASTC is the platform type, you need to actually select the corresponding folder according to the cook platform.

-compressIndicates that files are compressed when packaging pak.

tips

When we are packaging, check Edit\Project Setting\Packaging\Use Pak File

 

Then the packaged resources will be packaged into an independent Pak package. If it is not checked, the resource path will be the same as when editing.

3. Pak file mounting and loading

First create a class as a carrier to mount the code

//.h
#pragma once

#include "IPlatformFilePak.h"
#include "GenericPlatform/GenericPlatformFile.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "OperatActor.generated.h"

UCLASS()
class MYPROJECT_API AOperatActor : public AActor
{
	GENERATED_BODY()
	
public:	
	AOperatActor();
	TSharedPtr<FPakPlatformFile> PakPlatform;
	class IPlatformFile* OldPlatform;

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;
	
	void Mount();
};
//.cpp
void AOperatActor::BeginPlay()
{
	Super::BeginPlay();
	Mount();
}
void AOperatActor::Mount()
{
    //pak包的路径,如果是热更新则先将pak包下载到本地再挂载
	FString PakFileFullPath = TEXT("D:/Goulandis/Windows/PakTest_1_P.pak");
	//获取当前平台的文件操作链头
    OldPlatform = &FPlatformFileManager::Get().GetPlatformFile();
	if (!PakPlatform)//判断智能指针是否有效
	{
		PakPlatform = MakeShareable<FPakPlatformFile>(new FPakPlatformFile());
	}
    //初始化接口,
	PakPlatform->Initialize(&FPlatformFileManager::Get().GetPlatformFile(), TEXT(""));
    //设置初始化的配置
	FPlatformFileManager::Get().SetPlatformFile(*PakPlatform.Get());
	if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*PakFileFullPath))//判断文件是否存在
	{
         //从文件系统中获取pak文件的引用
		TSharedPtr<FPakFile> TmpPak = MakeShareable<FPakFile>(new FPakFile(PakPlatform.Get(),*PakFileFullPath,false));
		if (TmpPak)
		{
             //获取已经挂载的Pak文件,避免重复挂载
             TArray<FString> ExistPaks;
			PakPlatformFile->GetMountedPakFilenames(ExistPaks);
			if (ExistPaks.Find(PakName) >= 0) 
             {
				return;
		    }
             //拼接新的挂载点
			FString PakMountPoint = TmpPak->GetMountPoint();
			int32 Pos = PakMountPoint.Find("Content/");
			FString NewMountPoint = PakMountPoint.RightChop(Pos);
			NewMountPoint = FPaths::ProjectDir() + NewMountPoint;
             //设置新的挂载点
			TmpPak->SetMountPoint(*NewMountPoint);
			//挂载pak文件,如果挂载成功则返回true,否则返回false
			if (PakPlatform->Mount(*PakFileFullPath, 1, *NewMountPoint))
			{
                 //挂载成功后就可以在指定的挂载目录加载挂载内容了,这里偷了懒直接使用了完成路径
				UClass* uclass = LoadClass<AActor>(NULL, TEXT("Blueprint'/Game/Pak/PakTest.PakTest_C'"));
                 //蓝图类加载成功,就可以把Actor直接实例化到World中了
				if (uclass)
				{
					AActor* actor = GetWorld()->SpawnActor<AActor>(uclass, FVector(0), FRotator(0));
				}
			}
		}
	}
	FPlatformFileManager::Get().SetPlatformFile(*OldPlatform);
}

Here are some classes and functions that need to be explained:

  • IPlatformFile: This is UE4's most basic class for file operations. It defines related methods for file operations. UE4 itself encapsulates a file operation class instead of directly using C++ file operations. UE4 provides platform portability. To establish such a higher-level I/O interface;

  • FPakPlatformFile: This class is an encapsulation class for UE4's operation on pak files, derived from the IPlatformFile class;

  • FPlatformFileManager: This class is the encapsulation used by UE4 to obtain physical files of different platforms. The Get() method is to obtain the instance of the class itself. The GetPlatformFile() method is to obtain the chain head of the file operation chain. If it is not found, it returns nullptr;

  • Initialize(): Initialize the interface. The first parameter is the next file class object pointed to by the FPakPlatformFile class. We need to point to the current platform here. The second parameter is a command line. Some file classes will parse some parameters from here. Here we There is no command, so use an empty string;

  • SetPlatformFile(): It can be understood as the configuration initialized by Initialize() for the UE4 file system;

  • GetMountedPakFilenames(): Get the mounted pak files, the parameter is an FString array;

  • GetMountPoint(): Get the mount point of the pak file, which is directly stored in the pak file;

  • RightChop(): Returns the string to the right of the specified position of the string;

  • SetMountPoint(): Set the mount point. The mount point of the pak file must have a mount point, otherwise UE4 will not be able to find the pak file. The mount point is the upper directory of the pak file in UE4;

  • Mount(): Mount the pak file;

At this point, the mounting and loading of a pak file is completed, and the general process of the hot update of the game is 从服务器下载更新资源到本地-> 挂载本地资源-> 加载本地资源.

4. Pak package encryption and decryption

4. Resource update in the form of DLC

The form of the DLC is different from the form of the pak package only in the way the pak package is generated. The pak package is baked and packaged directly using the command line, while the DLC uses the ProjectLauncher. The final resources are downloaded in the form of a pak package. Locally, only the form of pak requires us to manually write C++ code to mount, while the form of DLC can automatically mount and load the pak file in the specified folder.

In the form of DLC, two ProjectLaunchers need to be configured, one for the packaged local ProjectLauncher and one for the packaged DLC ProjectLauncher.


 

Guess you like

Origin blog.csdn.net/qq769919187/article/details/122260372