虚幻引擎(UE5)携带Actor过关卡(附工程源码)
前言
虚幻引擎在定义关卡时,将关卡设定为是一个World,从关卡类型可以得知UWorld类型。一个世界具备一个世界的规则。两个不同的关卡可以使用相同的规则,但是不是同一个规则。就如同我们的法律中规定盗窃是犯罪,其他国家一样也有这样的法律规则。
并且虚幻引擎在一定意义上不允许有两个世界同时存在,所以当我们切换关卡时,旧有的关卡对象必然会被释放掉!而新关卡对象与旧有关卡无关。
那是否可以携带旧有关卡中的对象到新关卡呢?答案是可以的!只不过我们需要借助虚幻引擎中的无缝漫游设置。
注意:蓝图无法直接实现,需要依赖C++
步骤
- 开启无缝漫游,需要在Gamemode的代码中设置,或是在Gamemode蓝图面板中设置(二选一)。
1ACarryThroughGameModeBase::ACarryThroughGameModeBase()
2{
3 //应用无缝漫游 Gamemode构造函数中设置
4 bUseSeamlessTravel = true;
5}
或是在继承Gamemode的蓝图类面板中设置
- C++中Gamemode重写父类GetSeamlessTravelActorList函数
1virtual void GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList) override;
注意,此函数在切换关卡使用无缝漫游时会被调用,调用时,需要将漫游过关卡的Actor添加到参数ActorList中,即可将Actor携带过关。
实现代码参照
1void ACarryThroughGameModeBase::GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList)
2{
3 //需要优先调用,蓝图传入会覆盖ActorList
4 K2_GetSeamlessTravelActorList(ActorList);
5 //将自身存储数组数据追加到List数组中
6 ActorList.Append(TravelActorList);
7 //必须调用父类函数
8 Super::GetSeamlessTravelActorList(bToTransition, ActorList);
9}
其中K2_GetSeamlessTravelActorList是我添加的函数,用于向蓝图暴露,蓝图可重写,函数声明如下
1UFUNCTION(BlueprintImplementableEvent, DisplayName="GetSeamlessTravelActorList")
2void K2_GetSeamlessTravelActorList(TArray<AActor*>& ActorList);
TravelActorList是我在GameMode中添加的用来存储保存过关Actor的数组。
ACarryThroughGameModeBase.h源码
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源码
1#include "CarryThroughGameModeBase.h"
2
3ACarryThroughGameModeBase::ACarryThroughGameModeBase()
4{
5 //应用无缝漫游
6 bUseSeamlessTravel = true;
7}
8
9void ACarryThroughGameModeBase::GetSeamlessTravelActorList(bool bToTransition, TArray<AActor*>& ActorList)
10{
11 //需要优先调用,蓝图传入会覆盖ActorList
12 K2_GetSeamlessTravelActorList(ActorList);
13 //将自身存储数组数据追加到List数组中
14 ActorList.Append(TravelActorList);
15 //必须调用父类函数
16 Super::GetSeamlessTravelActorList(bToTransition, ActorList);
17}
18
19void ACarryThroughGameModeBase::AddTravelActorList(AActor* Actor)
20{
21 TravelActorList.Add(Actor);
22}
蓝图中重写函数截图
- 启动切换关卡 切换关卡时注意需要独立进程启动,并且不要使用Openlevel节点!可使指令节点,启用无缝切换地图。 指令命令参照(注意分割空格):ServerTravel /Game/Maps/l02
也可以在C++中调用代码切换,源码结构如下:
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);
源码位置:UWorld
效果展示
切换后Actor原有状态不变,数据不变。在一些设计中,仍需要考虑携带过关的Actor是否会关联其他对象,关联对象是否要被携带过关,所以这也是一个复杂的设计。
工程链接:传送门
提取码:2gcl
引擎版本: 5.1