Tutorial: Example Project: Loading Pak Files At Runtime

The PakDemo project demonstrates a standalone application created by an Unreal Engine Project that can load assets from a .pak file from the local filesystem or addressable path cooked in a separate project. This tutorial will walk through the provided sample of the PakTestContent project which will generate the Pak file and the PakDemo project which will load the Pak file at runtime.

https://dev.epicgames.com/community/learning/tutorials/7Bj8/unreal-engine-example-project-loading-pak-files-at-runtime

3 Likes

I found out that I was missing the windows build for the Pak file loader project, alluded to early in the tutorial. Apologies for that. I have updated the project zip files to remedy the situation. Thanks for the feedback!

This tutorial has been very useful for me to get started with Pak files, but there are still a couple things I would like to ask because I havenā€™t been able to find much more information on the subject, specially up to date with the latest versions.

With this we can load UAsset files from a Pak, which can be used to import pretty much any kind of object, actors, components, etc. But how about UMap files? Letā€™s say I want to import a whole level with its contents.

I tried adding one into the PakTestContent project (I placed it in pakTest/Core as well) and rebuilt the Pak. I also tinkered a bit with the PakDemo project to try and load this level. I modified the ā€œGetPakContentā€ function to include UMaps and made sure that the Pak did include it, but after that, the little stuff I found online simply stated that once the Pak was mounted I could ā€œOpenLevelā€ into it.

I tried, but this fails with a ā€œFailed to load packageā€ error popup that closes the game. As I said, the level is listed as included in the Pak, so Iā€™m kinda stuck here.

3 Likes

Hi @mikeweiss,

Firstly, thank you so much for your tutorial and the material.

Iā€™m very interested in this topic, and my case is similar to the case explained by @DarkiRuiz.

In my case, before changing the code, I tried to package the solution that you are sharing and execute the new packaged output. But, it crashes in the spawning step and the application is closed.

Could you help us with this?

Thank you in advance

Hi @mikeweiss, thank you for the tutorial! I have a question regarding using pak files in the editor. I have a pak filled with animations that I am able to mount, load, and use in the editor, but I am running into crashes when closing the editor during the RemovePlatformFile function in PlatformFileManager. Iā€™ve looked through source and the forums and seem to be finding some mixed messages regarding pak file usage in the editor so I was just wondering if you had any insight?

Iā€™m curious about this too.

Did you succeed to load a complete ā€œexternalā€ level?

I make a problem when the scene have a large models .


if no models it used ok

1 Like

No itā€™s a different reason. It doesnā€™t work with nanite meshes that werenā€™t rendered before mounting at the moment. I am trying to fix this as well. Changing levels also doesnā€™t work anymore after mounting

1 Like

I managed to get map loading from pak files to work, but all materials are replaced by Unrealā€™s default material and it also doesnā€™t work for maps with Nanite-enabled meshes.

For simple levels with nothing in them except maybe a sky and some boxes, it should be enough to modify your GetPakContent method to return umaps instead of uassets, take one of those pak content paths, throw it into Conv_PakContentPathToReferenceString to get its reference string and use that together with UGameplayStatics::OpenLevel to actually load it.

However, this doesnā€™t work if the map contains references to engine content. You can check if that is the case by unpacking the pak file containing your map and the assets it depends on with the UnrealPak tool located in the Unreal Engineā€™s Binaries folder. You can do this on Linux like so (on Windows itā€™s probably the same except you call UnrealPak.exe or something):

<your-unreal-installation-directory>/Engine/Binaries/Linux/UnrealPak -Extract <path/to/your/pakfile>/pakchunk1-Linux.pak" <output-path>

If the output folder only contains assets and folders from inside your projectā€™s content directory, youā€™re golden. If it instead contains a folder called ā€œEngineā€ and one whose name is your project name, you know your map has engine dependencies and you need to adapt the code a bit to get it to work with those kinds of pak files.

The first problem you will run into is that the aforementioned ā€œEngineā€ folder can also contain Content folders, which might be registered as mount points instead of your gameā€™s Content folder rather than additionally to it. You can mitigate this by modifying GetPakMountContentPath so that it returns a TSet<FString> of all the content paths instead of just an FString with the first one it can find, and obviously you need to change MountAndRegisterPak as well to register mount points for all these content folders instead of just the first one.

The second problem you might encounter is that Conv_PakContentPathToReferenceString may return incorrect reference paths. You need to make sure that this function takes into account the fact that both your pak fileā€™s mount point and the file paths you get from GetPakContent will be different if your map has engine dependencies. Trial and error will get you there, as long as you keep in mind that reference strings need to look something like this: /Game/SomeFolderInYouUnrealProject/YourMap.YourMap
and not like that:
/Game/YourProjectName/Content/SomeFolderInYouUnrealProject/YourMap.YourMap. At least that was an issue for me, but maybe I just refactored things wrong.

Sorry I canā€™t share any of my source code, btw. Iā€™ve re-written the sample projectā€™s code from scratch for a proprietary software project and Iā€™m not allowed to post that here on the internet, but posting small code fragments doesnā€™t make any sense either because my code is structured in a completely different way than the example project. I still hope that my hints can be of use to you.

Anyway, Iā€™d also quite appreciate an update to this guide with support for loading maps from pak files, with and without engine dependencies, with and without nanite-enabled meshes.

1 Like

Iā€™ve tried following along with what you have posted and whatā€™s in that demo and Iā€™m still stuck loading a map from a pak file from another projectā€¦ I have code that goes through the loaded pak file and just grabs the first .umap it finds and tries to load it. Iā€™m running it through Con_PakContentPathToReferenceString like you said and the path looks right. But it still tells me it canā€™t find that map:

LogPakFile: Display: Mounted Pak file ā€˜ā€¦/ā€¦/ā€¦/PakLoader/Paks/mypak.pakā€™, mount point: ā€˜/Game/ā€™
LogPackageName: FPackageName: Mount point added: ā€˜ā€¦/ā€¦/ā€¦/PakTest/Content/ā€™ mounted to ā€˜/Game/ā€™
LogTemp: Mounted Pak file successfully: ā€¦/ā€¦/ā€¦/PakTest/Content/
LogTemp: Pak file mounted successfully.
LogTemp: MountPoint ā€¦/ā€¦/ā€¦/PakTest/Content/
LogTemp: Loading level: /Levels/Exterior.umap
LogLevel: Warning: WARNING: The map ā€˜/Game/Levels/Exterior.Exteriorā€™ does not exist.

                if (this->MountPakFile(PakSavePath, MountPoint))
                {
                    UE_LOG(LogTemp, Log, TEXT("Pak file mounted successfully."));

                    TArray<FString> Content = GetPakContent(PakSavePath, false);
                    FString FirstLevel = FindFirstLevel(Content);
                    if (!FirstLevel.IsEmpty())
                    {
                        UE_LOG(LogTemp, Log, TEXT("Loading level: %s"), *FirstLevel);

                        const FString FileName = Conv_PakContentPathToReferenceString(FirstLevel, MountPoint);
                        UGameplayStatics::OpenLevel(this, FName(FileName));
                    }
                    else
                    {
                        UE_LOG(LogTemp, Warning, TEXT("No level found in the pak file."));
                    }
                }
                else
                {
                    UE_LOG(LogTemp, Error, TEXT("Failed to mount Pak file: %s"), *PakSavePath);
                }

Still stuck on this. Any thing I can try? Any more information I could provide that would be helpful?

Hi, Iā€™ve encountered a similar situation to yours. Have you made any progress on this issue?

Hi, I canā€™t start/compile the PakDemo project using UE 5.4.2.

image

Iā€™m a beginner at UE/C++ so Iā€™m not quite sure how to fix this.
After some googling I could get a Win64 Development Build to complete successfully from VSCode, by setting DefaultBuildSettings = BuildSettingsVersion.V5 inside PakDemo.Target.cs and PakDemoEditor.Target.cs
However, the same error as in the picture is still given when choosing yes to rebuild PakDemo now when starting the project.

The BuildSettingsVersion.V5 worked for compiling some old UE5.2 projects with 5.4.2, but I really have no idea what Iā€™m doingā€¦
I would be very happy for any help as I would really like to learn this topic.
Thanks

Update: There are some code changes in the PakFileReader(UpdatedCodebase_Oct2024).zip archive on box. The Blueprint functions are the same, but the underlying code has been modified a bit.

We plan to update the project demo in the coming weeks so stay tuned for an updated version. We have it working in 5.4 internally,

1 Like

Thanks! Looking forwards to the updated demo as this is quite a difficult topic to learn.

Hello,

thank you for the tutorial. On my side, I encountered problems (posted here) when generating the pak files from a project using a different name from the main application. So I finally used a project with the same name, but it appears to be a workaroundā€¦ Is there a cleaner solution?