I know this is old, but I’ll answer for any future people who
have the same question.
Using PrepareMapChange/CommitChangeMap:
Call ()->PrepareMapChange and give it a list of maps (FName list) starting
with the main (persistent level) first, followed by any sublevels that need to
be loaded at the spawn point. Example:
TArray<FName> Levels;
Levels.Add(MainLevel);
Levels.Add(Sublevel1);
Levels.Add(Sublevel2);
The FNames must be in the form:
FName MainLevel = "/Game/Maps/MyLevelName";
Note that the extension is not being used, and we use “/Game” rather than
“/Content”. If you have a filepath, you can covert it to the needed format,
called a “Long Package Name”, by calling:
FPackageName::FilenameToLongPackageName(MyFilePath)
If you neglect to add a needed sublevel to the list sent to PrepareMapChange,
the call to CommitMapChange will block for however long it takes to load and
set up the neglected level.
To check to see if the maps are done preloading use:
if(()->IsMapChangeReady && !IsAsyncLoading())
That second part is important because IsMapChangeReady tells you if the levels
sent in the list to PrepareMapChange are ready, but not if any sublevels or
assets those maps reference are ready.
When done call:
()->CommitMapChange();
It’s important NOT to call the GEngine version of the same file. The UWorld
version makes sure the call is done the right way.
When CommitMapChange is done, there will be a callback to
GameMode::PostCommitMapChange(). Teleport the player and do any setup
necessary for the new level there. Note that TeleportTo will not change the
orientation of the Player, so you need to set that manually by calling
MyPlayerController->SetControlRotation(LevelPlayerStart->GetActorRotation());
How long the switchover takes after calling CommitMapChange depends on how
long the garbage collection takes when clearing the old level. If you’re
exiting a small level, then the transition is very small. On my tests with
large levels, the switch over took about a second and a half. Usually a quick
fade-out, CommitMapChange, fade-in can easily hide the transition.
This method will NOT work in “Play In Editor” mode (PIE). You must run it
in Standalone mode to see it.
Hope this helps.
…
EDIT: To make this pipeline work in PIE mode:
- In EditorEngine.cpp (Engine\Source\Editor\UnrealEd\Private):
In UEditorEngine::Tick:
Look for the first inner loop that contains the line:
FWorldContext &PieContext = *ContextIt;
Near the end of that loop add:
ConditionalCommitMapChange(PieContext.World());
- In UnrealEngine.cpp (Engine\Source\Runtime\Engine\Private):
In UEngine::CommitMapChange:
After:
if(bWasFound)
{
Add:
if (Context.WorldType == EWorldType::PIE)
StreamingLevel->RenameForPIE(Context.PIEInstance);