UE 关卡切换

阿赵UE引擎C++编程学习笔记——场景加载和切换_ue addstreaminglevel-CSDN博客

【UE】大世界子关卡StreamingLevel加载流程源码浅析-虚幻4_ue4 streaminglevel-CSDN博客

基础知识

        关卡可分为两类:持久关卡(PersistentLevel),子关卡或者流关卡(StreamingLevel)

持久关卡(PersistentLevel):默认加载进内存,它将会一直加载,无法卸载
子关卡或者流关卡(StreamingLevel):动态加载到内存(根据玩家位置和关卡距离,在运行时进行动态加载。)

1.直接切换

        所谓切换关卡,就是从当前关卡进入到一个新的关卡, 旧关卡的数据将会被放弃。进入新的关卡后,将会执行新关卡的关卡蓝图和GameMode的生命周期。但是需要注意GameInstance里的数据并不会清除,因此此时需要注意GameInstance的数据是否会影响。

如:

  • 在GameInstance里定义了变量 A = 10, GameMode A = 10, 同时改变变量 A = 20,重新切换关卡后GameInstance A = 20, GameMode A = 10。切换关卡可以重置大部分数据,但是需要注意无法重置的数据。
  • 一个关卡对应一个GameMode,切换关卡后,需要重新给GameMode赋值,这也是外什么GameMode的数据会重置

个人理解

  1. 当当前关卡不会在用时,如游戏中的地图切换,这样可以减小开销,减小不必要的性能消耗
  2. 某些时候的垃圾回收,当场景中Actor需要更新时,发生卡顿,又不知原因时使用(不是很建议,因为涉及数据的重新赋值,且Actor过多时会发生卡顿)

蓝图中节点

2. 加载实例 

 加载关卡和切换关卡不一样的地方是,原有的关卡并不会被卸载,而是把新的关卡直接加入到旧的关卡当中。然后生命周期还是走的原有关卡,新关卡只是用于加载资源。

个人理解

类型更新,在原有的基础上添加新东西

蓝图

 这个方法会返回是否加载成功,还有会返回加载后的Level对象,可以用于后续的控制:
在这里插入图片描述

 3.  通过流读取关卡

        区别于上面第2种方法,通过StreamLevel来加载场景,必须先把场景设置到Level里面。这是因为,一个主关卡可以添加很多个子关卡,这些子关卡可以设置成并不是一开始就加载,而是有需要的时候才加载显示。而很多个子关卡组成一个大关卡,就能实现超大型地图场景了。

个人理解

一个大关卡由多个小关卡构成,且每个小关卡有自己的数据与生命周期,如关卡蓝图

接下来看看怎样添加子场景。比如我要把Level2场景作为Level1场景的子场景,那么我们应该打开Level1场景,然后再去窗口——>关卡,打开关卡面板:
在这里插入图片描述

  然后把Level2拖动到关卡面板
在这里插入图片描述

然后把Level2的修改流送方法改成蓝图:
在这里插入图片描述

蓝图:需要时加载
固定加载:默认就加载 

 设置好了之后,通过Load Stream Level节点,就可以加载子场景了。可以通过引用或者场景名称来加载。如果没有上面的设置,加载的时候会报错说找不到该名字的流场景。
在这里插入图片描述

        这里有个设置叫做Make Visible After Load,意思是在场景加载完的时候,是否需要显示出来,如果勾上,那么加载完成后,就自动显示了。

        如果想后面再显示场景的显示,可以这样:

  • 通过GetStreamingLevel节点,可以找到刚才加载的StreamLevel
  • 通过Set Should Be Visible节点,可以设置Level是否显示
  • 如果想知道某个Level当前是否显示,可以用is Level Visible节点来查看

C++实现

1、 切换关卡

和蓝图的OpenLevel节点相同,都是加载新场景放弃就场景,调用如下:

UGameplayStatics::OpenLevel(GetWorld(), “Level2”);

2、 通过StreamLevel加载

这个和蓝图的Load Stream Level节点功能基本一致,也是需要先去关卡面板把子场景添加好,才能正常加载:

加载

FString fileName = TEXT("Level2");
FLatentActionInfo info;
UGameplayStatics::LoadStreamLevel(GetWorld(), *fileName, true,false,info);

卸载

FLatentActionInfo info;
FString fileName = TEXT("Level2");
UGameplayStatics::UnloadStreamLevel(GetWorld(), *fileName, info, false);

控制

FString fileName = TEXT("Level2");
ULevelStreaming* curLevel = UGameplayStatics::GetStreamingLevel(GetWorld(), *fileName);
if (curLevel == nullptr)
{
    return;
}
bool isVisible = curLevel->IsLevelVisible();
curLevel->SetShouldBeVisible(not isVisible);

3、 按路径加载Level

如果不想先设置子Level,而直接按照路径加载某个场景资源,可以这样:


加载

ULevelStreamingDynamic* StreamingLevel;

FString path = TEXT("/Game/Level/Level3");
FLatentActionInfo info;
StreamingLevel = NewObject<ULevelStreamingDynamic>(GWorld, ULevelStreamingDynamic::StaticClass(), NAME_None, RF_Public, NULL);
StreamingLevel->SetWorldAssetByPackageName(*path);
GetWorld()->AddStreamingLevel(StreamingLevel);
StreamingLevel->SetShouldBeLoaded(true);
StreamingLevel->SetShouldBeVisible(true);


控制和移除

需要自己保存之前加载的StreamingLevel,接下来可以控制该Level的显示隐藏或者卸载移除都可以

if (StreamingLevel != nullptr)
{
StreamingLevel->SetIsRequestingUnloadAndRemoval(true);
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值