note 1:
The patching process creates a pak file in [ProjectName]\Saved\StagedBuilds[PlatformName][ProjectName]\Content\Paks. This pak file is the patch that should be distributed to users. For example, on Windows, you would create an installer to copy that pak file into the userās [ProjectName]\Releases[VersionNumber][PlatformName] folder, next to the original content pak file.
note 2:
Copy the pak file from ShooterGame\Releases\1.0\WindowsNoEditor to ShooterGame\Saved\StagedBuilds\WindowsNoEditor\ShooterGame\Content\Paks
My english is not very good but i understand the following:
note 1: ācopy from Content/Paks to Releases/ā
note 2: ācopy from Releases/ to Content/Paksā
The good news is they donāt speak about any code modification so whatever the directory used, i guess itās supposed to be automatic.
Content/Paks seemed the natural candidate as it already contains the main pak file and works very well with it.
But you never know unless you try.
I didnāt test the Releases/ dir yet, so iāll have to.
Iāll go on with my tests while iāve some energy left for this and will of course let everyone know here if i make some (lucky) progress.
Otherwise iāll end up doing what you did: put this aside and wait for some solid support from epic.
I had code for umapās working on 4.10 using :
FCoreDelegates::OnMountPak // and
IFileManager::Get().FindFilesRecursive(mapFiles, FPaths::GameContentDir(), TEXT(".umap"), true, false);
But itās no longer working :(. I did a bit of debugging and diffing source files, but havenāt found the regression yet. Iāll take another pass at this later, but need to get other things done for the moment.
The problem is that the mount path set internally does not work for me. This allows me to explicitly set it to gameDir which does work. I would like to find a better way to get the FPakPlatformFile* since this method is very fragile, but it does work.
Hope this helps someone, and that this isnāt necessary in the future.
Iām still trying to get things sorted.
It will be a huge help for people like me if any of you can explain the Mount Point thing with actual paths.
Just ignore whether those assets are cooked or not.
For example here are the given pathes
My Create file c:\create.txt
Asset file1 c:\asset\book1.uasset
Asset file2 c:\Program Files\EpicGames\4.12\Engine\Content\book2.uasset
Asset file3 c:\412\MyProject\Content\book3.uasset | (In game content path)
Engine path c:\Program Files\EpicGames\4.12\Engine
What would be the Command to Generate Pak File?
c:\Program Files\EpicGames\4.12\Engine\Binaries\Win64\UnrealPak.exe <OutPak.pak> -create=c:\create.txt -Dest=???
With the āOld Methodā what would the mount point and AssetRef be?
Result = PakPlatformFile->Mount(*File, NewOrder, *FPaths::GameContentDir());
return true in editor and standalone launch but i havenāt access to files. (In this case i used not cooked assets)
The problem is very bad when i create my shipping version of project and cooked assets when i try to load an assets project crash! Again that funcrtion return true for mounting .pak file.
I was able to get something using a second project with the same name.
!!!THIS IS STILL WORK IN PROGRESS AND THE RESULTS ARE NOT AS EXPECTED!!! See below.
EDIT:
Solved my issues, see EDIT below.
From your main project go to File->PackageProject->Windows->WindowsPlatform
Chose MainPackageDir
Make a second project that has the EXACT SAME PROJECT NAME but in a different directory
Add some materials to Content/Mods
Package the second project the same way as the first
Chose a SecondPackageDir
Go to SecondPackageDir/WindowsNoEditor/PROJECTNAME/Content/Pak
Rename the .pak to ProjectName_Mod.pak (or Whatever.pak) as at the moment it is the same filename as the main project and that will not work.
Copy the ProjectName_Mod.pak to MainProjectDir/WindowsNoEditor/PROJECTNAME/Content/Pak
Start .exe of the main project
But nothing happend? Right, how could it? The assets are only mounted correctly at the moment, not used in the game.
So how to access the stuff:
Create a C++ BlueprintFunctionLibrary and add the following function.
/**
* Get (and load) all assets from a folder relative to GameDir/Content that match the class.
*
* @param assetClass Class of the assets to look for
* @param path Path is relative to GameDir/Content e.g. "/somepath". NOTE: "" or "/" WILL NOT WORK!!!
* @param assets OUT: The assets found
*/
UFUNCTION(BlueprintPure, Category = "Utility", meta = (DeterminesOutputType = "assetClass", DynamicOutputParam = "assets"))
static void GetAllAssetsInDirectoryRecursive(const TSubclassOf<UObject> assetClass, const FString path, TArray<UObject*>& assets);
{
UObjectLibrary* objectLibrary = UObjectLibrary::CreateLibrary(assetClass.Get(), false, true);
objectLibrary->LoadAssetsFromPath(*(FString(TEXT("/Game")) / path));
objectLibrary->GetObjects(assets);
// As the library is a UObject it should be picked up by the GarbageCollector now *pray*
}
Add the function in your code where you want to access the assets and package the main project again.
Run the .exe of the main project
The C++ function works flawlessly within the main project.
My Issues:
Iām currently only trying with textures and materials from the mod
-Textures seem to work without issue
-Materials are bugged at this time. Just a simple red material from the mod shows up as a high specular glitch that changes color depending on time and view angle
-This only works when restarting the game, not at runtime.
And as we package the mod project the normal way, we also include engine content that we donāt want. This might also lead to my material issue. The mod.pak is ~100MB for a simple texture and material.
Can somebody explain how to use FCoreDelegates::OnMountPak? Is see that you need to call .Execute on it, and when the engine is bound to it, it will load the specified file. But as always, the signature parameters are not documented.
// delegate type for prompting the pak system to mount a new pak
DECLARE_DELEGATE_RetVal_ThreeParams(bool, FOnMountPak, const FString&, uint32, IPlatformFile::FDirectoryVisitor*);
FString&: should be the path to the .pak
uint32: Goes to PakOrder, see below. Seems to be the order in which pak files are read. Highest number = loaded first.
IPlatformFile::FDirectoryVisitor*: what is this needed for and what to give it? Need to create a new FDirectoryVisitor or do we need to get on already existing from somewhere?
If OnMountPak is bound by FPakPlatformFile, it delegates to
/**
* Handler for device delegate to prompt us to load a new pak.
*/
bool HandleMountPakDelegate(const FString& PakFilePath, uint32 PakOrder, IPlatformFile::FDirectoryVisitor* Visitor);
Not yet. Had a look at it, but it seems more to be for assets in the main project and loading them in when needed. Not loading .pak at runtime and getting references to the stuff.
What you had in mind with the Asset Manager exactly? Packaging out? Loading in? Both?
Also it seems you need to work with primary assets and bundles to make use of the Asset Manager. Iām looking into this for modding and it should be possible to just create a material and package that out, load it in the other project. This must work at runtime, as we are going for mod support and multiplayer (ya know, the āI want to connect to server but I miss the modsā issue).
Assign your game content to have different chunkIds and then they will be compiled into different paks and you can send and download these into a game as dlc!
Also this is how Valorant does it, go into val content folder and you see: