Unreal Engine (UE5) Carrying Actor Through Levels (with Project Source Code)

Preface

When defining a level, Unreal Engine sets the level as a World. The UWorld type can be known from the level type. A world has its own rules. Two different levels can use the same rules, but they are not the same rules. Just as our laws stipulate that theft is a crime, other countries also have such legal rules.

And Unreal Engine does not allow two worlds to exist at the same time in a certain sense, so when we switch levels, the old level objects will inevitably be released! And the new level objects have nothing to do with the old level.

So can we carry objects from the old level to the new level? The answer is yes! But we need to use the seamless roaming settings in Unreal Engine.

Note: Blueprint cannot be implemented directly, and needs to rely on C++

Steps

  1. To enable seamless roaming, you need to set it in the Gamemode code or in the Gamemode blueprint panel (choose one of the two).
1ACarryThroughGameModeBase::ACarryThroughGameModeBase()
2{
3    //Set in the Gamemode constructor to apply seamless roaming
4    bUseSeamlessTravel = true;
5}

Or set in the blueprint class panel that inherits Gamemode

GameMode details panel

  1. Gamemode overrides the parent class GetSeamlessTravelActorList function in C++
1virtual void GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList) override;

Note that this function will be called when seamless roaming is used when switching levels. When calling, the Actor that roams through the level needs to be added to the parameter ActorList, so that the Actor can be carried through the level.

Implementation code reference

1void ACarryThroughGameModeBase::GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList)
2{
3    //Need to be called first, blueprint input will overwrite ActorList
4    K2_GetSeamlessTravelActorList(ActorList);
5    //Append the self-stored array data to the List array
6    ActorList.Append(TravelActorList);
7    //Must call the parent class function
8    Super::GetSeamlessTravelActorList(bToTransition, ActorList);
9}

K2_GetSeamlessTravelActorList is the function I added, which is used to expose to the blueprint. The blueprint can be overwritten. The function declaration is as follows

1UFUNCTION(BlueprintImplementableEvent, DisplayName="GetSeamlessTravelActorList")
2void K2_GetSeamlessTravelActorList(TArray<AActor*>& ActorList);

TravelActorList is the array I added in GameMode to store the Actors that have passed the level.

ACarryThroughGameModeBase.h source code

 1#pragma once
 2 
 3#include "CoreMinimal.h"
 4#include "GameFramework/GameModeBase.h"
 5#include "CarryThroughGameModeBase.generated.h"
 6 
 7/**
 8 * 
 9 */
10UCLASS()
11class CARRYTHROUGH_API ACarryThroughGameModeBase : public AGameModeBase
12{
13    GENERATED_BODY()
14 
15 
16    ACarryThroughGameModeBase();
17     
18protected:
19 
20    virtual void GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList) override;
21 
22    UFUNCTION(BlueprintCallable)
23    void AddTravelActorList(AActor* Actor);
24    UFUNCTION(BlueprintImplementableEvent, DisplayName="GetSeamlessTravelActorList")
25    void K2_GetSeamlessTravelActorList(TArray<AActor*>& ActorList);
26 
27protected:
28     
29    UPROPERTY()
30    TArray<AActor*> TravelActorList;
31};

ACarryThroughGameModeBase.cpp source code

 1#include "CarryThroughGameModeBase.h"
 2
 3ACarryThroughGameModeBase::ACarryThroughGameModeBase()
 4{
 5    //Apply seamless roaming
 6    bUseSeamlessTravel = true;
 7}
 8
 9void ACarryThroughGameModeBase::GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList)
10{
11    //Need to be called first, the blueprint will overwrite ActorList
12    K2_GetSeamlessTravelActorList(ActorList);
13    //Append the self-stored array data to the List array
14    ActorList.Append(TravelActorList);
15    //Must call parent class function
16    Super::GetSeamlessTravelActorList(bToTransition, ActorList);
17}
18
19void ACarryThroughGameModeBase::AddTravelActorList(AActor* Actor)
20{
21    TravelActorList.Add(Actor);
22}

Screenshot of overriding function in blueprint

BP_Gaemode inherits from ACarryThroughGameModeBase

  1. Start switching levels When switching levels, please note that an independent process needs to be started, and do not use the Openlevel node! You can use the command node to enable seamless map switching.
    Command reference (note the separator space): ServerTravel /Game/Maps/l02

You can also call code switching in C++, the source code structure is as follows:

1    /**
2     * Jumps the server to new level.  If bAbsolute is true and we are using seemless traveling, we
3     * will do an absolute travel (URL will be flushed).
4     *
5     * @param URL the URL that we are traveling to
6     * @param bAbsolute whether we are using relative or absolute travel
7     * @param bShouldSkipGameNotify whether to notify the clients/game or not
8     */
9bool ServerTravel(const FString& InURL, bool bAbsolute = false, bool bShouldSkipGameNotify = false);

Source code location: UWorld

Effect display

Original level
New level

After switching, the original state of the Actor remains unchanged, and the data remains unchanged. In some designs, it is still necessary to consider whether the Actor that carries through the level will be associated with other objects, and whether the associated objects will be carried through the level, so this is also a complex design.

Project link: Portal

Extraction code: 2gcl

Engine version: 5.1

Translations:

Comment