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
- 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 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
- 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
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