How to load a map from a dynamic level

Hi,

I’ve managed to dynamically load a pak with FCoreDelegates::OnMountPak.Execute() but it fails when I try and load a map from it.

I’ve tried ServerTravel and UGameplayStatics::OpenLevel - OpenLevel returns an error that the map cannot be found - the map is specified as the name returned when I look at it’s reference from the editor (e.g. /Game/MyMap.MyMap).

Has anyone found any useful documentation on doing this, or have any clues as to what could be going wrong?

Thanks,

Richard.

Is there someone at Epic that can help me with this please?

After seeing an example where an asset was being loaded with a “StaticMesh’’” wrapper I found that “Copy Reference to clipboard” provides something similar to World’/Game/MyMap.MyMap’. I plugged that into my code but the results are the same - OpenLevel has no return code so can’t tell if it has failed apart from the fact that UE is still displaying the old levels map. Anyone?

Hi again if anyone is reading…

Some more information provided:

Saving a map to the base project and loading that with UGameplayStatics::OpenLevel works fine.

Either “World’/Game/MyMap.MyMap’” or “MyMap” appear to work.

When attempting to load the dynamically loaded pak file it looks like it’s trying to load - it creates a new UWorld and a new GameMode - calls the GameMode::InitGame method. Querying the new World returns the base projects Map name though and the old map is still displaying. The log file tells me that it has loaded, no error entries.

Update:

I had my Oculus Rift plugged into the HDMI but not USB, I unplugged the HDMI and now I am getting error messages about not finding the map in the log file - most strange, but also much more helpful - Still, I’ve tried all incantations of the map name and it still does not find it.

Ok, looks like the level name takes on the base games hierarchy? I specify the level name now as “/Game/BaseGame.newlevel” and it appears to load and then exit - at least it’s progress…

Still stuck… I get this error now:

LogPackageName: SearchForPackageOnDisk took 0.018s, but failed to resolve MyMap.umap.

It appears that /Game/ is mapped to the original game still, so when specifying /Game/SubMap.umap it’s mapping it to “…/…/…/LauncherGame/Content/”.

Using just the “SubMap” name gets through the path finding routines but then barfs later with that “failed to resolve” error. It sounds like short-names are not supported in standalone anyway.

I even tried laying out the map and data in my dynamic pak into the same folder hierarchy and names as the launcher project but that doesn’t work either.

sigh…

There’s a function you can call to mount a pak to a root path (/game, /engine etc). Away from computer at the moment but I found it when searching the engine code for an error about root names.

The comments implied that use of this would allow you to override existing asset access with new assets. As soon as I called it the engine mounted assets in my pak and I’ve been able to load utextures and usoundcues using short paths - including in standalone builds.

Might not help you but here’s the code I’ve got to mount pak files (not tested umaps yet). The first few lines are setting the mount point to the pak file location so files can be pathed relative to that - MakeStandardFilename is very important in the approach I take - the internal pak file directory structure is quite sensitive to paths.

RegisterMountPoint makes my files accessible using the short file names. In this case a filename of a/b/c.uasset within the pak would become /dlc/a/b/c

The output after has proven useful while working through my own pak file woes, so I’ve included it here.

	FString StandardFilename(rPakFileName);
	FPaths::MakeStandardFilename(StandardFilename);
	StandardFilename = FPaths::GetPath(StandardFilename);
	
	if (!mp_DLCPakFiles->Mount(*rPakFileName, 0, *StandardFilename))//DLCPakMountPoint))
	{
        Errorf(_T("DLC - Unable to mount pak file '%s' to '%s'"), *rPakFileName, *StandardFilename);
		return false;
	}

	FPackageName::RegisterMountPoint("/DLC/", StandardFilename);
	//TODO UnRegisterMountPoint

#if MM_DEBUGrPakFileName
	struct Dump : public IPlatformFile::FDirectoryVisitor
	{
		virtual bool Visit(const TCHAR* FilenameOrDirectory, bool bIsDirectory)
		{
			if (bIsDirectory)
			{
				Outputf(_T("Directory: %s"), FilenameOrDirectory);
			}
			else
			{
				Outputf(_T("File: %s"), FilenameOrDirectory);
			}
			return true;
		}
	};
	Dump visitor;
    mp_DLCPakFiles->IterateDirectoryRecursively(*StandardFilename, visitor);
#endif

Thanks this helps a lot!

The FPackageName::RegisterMountPoint() was what I was missing.

So far adding that to my code I can now load maps ok but the assets contained in the maps… not so much… will keep working on that.

The Mount point from what I can tell is the original file location of the pak contents rather than the location of the created pak file - this may be because I’m loading a pak with FCoreDelegates::OnMountPak.Execute(). Is your mp_DLCPakFiles a folder on disk?

I also noted that if I have a uasset file located on disk at the location I add for the MountPoint, it will load that asset before checking the mounted pak file - that ones a bit of a trap…

Will keep working on the asset loading… Thanks.

Hello, when you load the map, the path map should specify how? Which way are you using to load map?

Hi,

Think of it as an extension to the file system - I load the map after setting a mount point like this:

FPackageName::RegisterMountPoint("/Game/","path to my map");
UGameplayStatics::OpenLevel(World,"LevelName");

The “path to my map” is the physical path on disk to the map file (excluding the map name) - it can be embedded in a pak file or just be a umap file on disk. The “/Game/” is the root path you want to map it to - “/Game/” is just where I have things, you can place them in other folders within that.

Do you mean the assets within the pak file - are you trying to load those? If so, the path to them should be relative to the mount point you set. If you used “/Game/” which is the root you would specify “Meshes/MyMesh.uasset” for a mesh that is located in a “Meshes” folder.

I loaded map from pak file, it can be loaded into the map, but the map of uasset gone, how to load the map with uasset?
Thanks.

Hey RichardB, I know this is a couple years old but I was wondering if you ever managed to get the assets in the map loading as well? I’m struggling with this right now

Hi TestyRabbit. Yeah I did get it working - I’ve attached a link to the sourcecode I used (there are a lot of commented out bits from various attempts but it successfully loads maps and assets… The link for the cpp file is: http://r4nc1d.com/files/deepHelpers.cpp - the LoadMap() function is the one with the important bits in it, I call it from my app with LoadMap(“Footprints”,"/Game/",“c:\Program Files (x86)\Slidescape\Content\Scenes\Deep\Footprints”) The assets all have to be cooked first, and then packaged with the Unreal Package program UnrealPak.exe…

Holy cow you’re a lifesaver. I’m working on some other stuff but I’ll have to take a look at this tomorrow. Thank you, if I have questions I may reach out if that’s alright. this has been a real big ■■■■■ haha.

So I’m looking through this file you sent me, it seems the only thing not commented out is essentially this block here:

bool triggerLevelLoad = true;
FString triggerLevelName = levelname;

FString ln;

if (mountPoint.Len()>0 && mountPath.Len()>0) {

    FPackageName::RegisterMountPoint(mountPoint, mountPath);
    ln = levelname;

}
else {
ln = levelname;
}

FName level(*ln);
UGameplayStatics::OpenLevel(GetWorld(), level);

This does all of it?

When it comes to mounting, did you use the FCoreDelegates approach? Because my issue with that approach is that after I mount the pak with that, it is unable to resolve the map name. If I use the PakFile approach I’m able to find the map but all of the assets are gone.

This is the path that my map is at in the pakfile: USETHIS/Content/test.umap (The visitor prints this out). Does that mean that I would call it like this? LoadMap("test", "/Game/", "D:\\UE4\\4.17\\USETHIS\\Content");, I’m trying to load the map into a project called “PakTest” located at “D:\UE4\4.17\PakTest\”

Yeah that’s the bits that are needed - the rest is experiments, I did this a number of years ago so it’s a bit foggy but I do remember having the same issue with the FCoreDelegates approach even though there were a number of people recommending it. This was the only way I could get the maps and all assets to load.
I also remember trying to use a separate folder like “USETHIS” but that didn’t work for me either so I stuck with “/Game/” and made sure all assets were within that folder (or subfolder).
If your map is called “test” and the folder it resides in is “D:\UE4\4.17” those should be the parameters - so it would be LoadMap(“test”,"/Game/",“D:\UE4\4.17”);