Mounting pak files at runtime

I am trying to make content (static meshes) available after my application is shipped. The plan was to

  1. add the dynamic content to the editor
  2. cook and pack it into a .pak file
  3. provide the .pak file on an http server
  4. download the pak with the shipped client
  5. mount the pak file and instantiate the content

1-4 are easy, but I could not get 5 done. I’m aware of [this post][1], but I don’t need any streaming, and I need to store the pak files at the client for offline availability.

For now, I tried the following (error checks omitted):

IPlatformFile& InnerPlatform = FPlatformFileManager::Get().GetPlatformFile();
FPakPlatformFile* PakPlatform = new FPakPlatformFile();

PakPlatform->Initialize(&InnerPlatform, TEXT(""));

FPlatformFileManager::Get().SetPlatformFile(*PakPlatform);

PakPlatform->Mount(Text("ABS_PATH_TO_PAK_FILE"), 0, *FPaths::EngineContentDir());

// trying to load the mesh
UStaticMesh* obj = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), nullptr, TEXT("/Engine/PAK_INNER_DIR")));

I am not sure if the “PAK_INNER_DIR” (this is obviously a placeholder) is incorrect, or if I just understood something wrong with mounting paks.

Any suggestions?

Stream an asset from the internet - Blueprint - Epic Developer Community Forums

Ok, now it works with Windows, but not with Android. There should not be much difference, right?

Could u share the code you are using to do that please ?

What did you change to make it work with Windows?
Can you show the complete program? I have a similar problem.

same problem I have, Could u share the solution?

Hey Everyone,

I’m not quite sure what you’re trying to do when you ‘mount the pak file and instantiate the content’, as that isn’t too clear to me. If you could explain this step further, I can dig deeper into our documentation and test this for you. With that being said, I’ve gathered a few AnswerHub posts and Documentation links that I feel may be helpful to what you’re trying to achieve:

  • [Mounting .pak files at runtime][1]
  • [Loading map from pak at runtime][2]
  • [FPakFile Documentation][3]
  • [Patch and DLC Support][4]

Thanks!

Mounting pak files at runtime - World Creation - Epic Developer Community Forums
[2]: Loading Map from Pak at Runtime - Programming & Scripting - Epic Developer Community Forums
[3]: FPakFile | Unreal Engine Documentation
[4]: Patch and DLC support - Platform & Builds - Epic Developer Community Forums

Yeah, can you share the code? How did you manage to solve this?

@CodeFluegel: Were you able to get it done. Kindly let me know how you did it. I am facing Engine crash.

If anyone could provide a blueprint C++ class for this that would be amazing!

!!DO NOT USE THE CODE FROM THREAD CREATOR!!

The code modifies the PlatformFile-Chain, which causes issues.
Doing so, we had issues with IFileManager::FindFilesRecursive which was now returning multiples of the same file (~6 times the same file in our case) (the issue appeared only in a packaged project).
Might be there are other issues as well.

The below code is modified to first look for a PakPlatformFile already existing in the PlatformFile-Chain and take that if it exists. That solved our issue.

//Load and mount pak file
    if (pakPlatformFile == nullptr)
    {
        // Search for an existing pakPlatformFile
        IPlatformFile* existingPakPlatformFile = FPlatformFileManager::Get().FindPlatformFile(TEXT("PakFile"));

        if (existingPakPlatformFile)
        {
            pakPlatformFile = static_cast<FPakPlatformFile*>(existingPakPlatformFile);
            UE_LOG(LogTemp, Log, "Using existing PakPlatformFile");
        }
        else
        {
            // When mounting a .pak file, we need to store a references to the .pak file in the platform file system.
            // To do this, we need a FPakPlatformFile that allows us to mount our .pak and keeps the information about the package.
            pakPlatformFile = new FPakPlatformFile();
            // But we don't want the engine to lose information of other packages
            // (and what ever other stuff), thus get the current PlatformFile
            IPlatformFile& platformFile = FPlatformFileManager::Get().GetPlatformFile();
            // and place it into our new PlatformFile (PlatformFile-Chain).
            if (!pakPlatformFile->Initialize(&platformFile, TEXT("")))
            {
                UE_LOG(LogTemp, Fatal, "Failed to initialize PakPlatformFile");
            }
            // Not sure about this, see: https://answers.unrealengine.com/questions/574388/how-to-mount-a-pak-file-at-game-content-directory.html
            pakPlatformFile->InitializeNewAsyncIO();
            // Now give the new PlatformFile to the engine.
            FPlatformFileManager::Get().SetPlatformFile(*pakPlatformFile);

            UE_LOG(LogTemp, Log, "Using our own PakPlatformFile");
        }
    }

if someone stumbles onto this page, epic already provides a guide and example project for people to look into.

1 Like