在虚幻引擎中使用C++加载和卸载关卡

您所在的位置:网站首页 烘焙教程已付费怎么取消 在虚幻引擎中使用C++加载和卸载关卡

在虚幻引擎中使用C++加载和卸载关卡

2023-05-19 18:21| 来源: 网络整理| 查看: 265

本页面的内容

使用C++在关卡中流送

使用C++卸载关卡

我们想在此处的露台关卡中开始流送,这样在玩家转过拐角并开始靠近露台时,流送中的关卡 就会加载好并可见。

作为设置的一部分,我们有两个关卡:SunTemple_Persistent 和 SunTemple_Streaming 。我们的 玩家出生点(Player Start) 位于 SunTemple_Persistent 中,我们的玩家在游戏中 由 角色 表示。

在 内容浏览器(Content Browser) 中打开 SunTemple_Persistent 。

将 玩家出生点(Player Start) 移至模板的最开头。

点击 窗口(Windows),然后选择 关卡(Levels) 。

点击 关卡(Levels) 下拉菜单,然后选择 添加现有...(Add Existing...) 以添加新的子关卡。

选择 SunTemple_Streaming 以添加 打开关卡(Open Level) 对话框,然后点击 打开(Open) 。

右键点击 持久关卡(Persistent Level) ,并从下拉菜单选择 设为当前(Make Current) 。

使用C++在关卡中流送

打开 内容浏览器(Content Browser) 并创建新 C++类 。此类将基于 Actor ,因此选择 Actor 并点击 下一步(Next) 。

将新 C++类 命名为"LevelStreamerActor",然后点击 创建类(Create Class) 。该新类将在Visual Studio或XCode中打开。

对于这种情况,我们需要在 角色 与LevelStreamerActor中称为OverlapVolume的BoxComponent重叠时立即流送第二个关卡。

在 LevelStreamerActor.h 中,声明一个具有VisibleAnywhere、BlueprintReadOnly属性且有AllowPrivateAccess meta标记的OverlapVolume。

private: // 重叠体积以触发关卡流送 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) UBoxComponent* OverlapVolume;

1.在 LevelStreamerActor.cpp 的LevelStreamerActor构造函数中,创建OverlapVolume并将其设为RootComponent。

OverlapVolume = CreateDefaultSubobject(TEXT("OverlapVolume")); RootComponent = OverlapVolume;

回到 LevelStreamerActor.h 中,声明一个受保护OverlapBegins函数,它将绑定到BoxComponent的OnComponentBeginOverlap函数。此绑定意味着, OverlapBegins必须标记有UFUNCTION宏,并且必须拥有与OnComponentBeginOverlap相同的签名。

protected: UFUNCTION() void OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);

同样在 LevelStreamerActor.h 中,创建一个EditAnywhere且名为LevelToLoad的受保护FName变量。这样一来,你就可以逐实例更改LevelToLoad。

UPROPERTY(EditAnywhere) FName LevelToLoad;

我们将使用GameplayStatics库中的一些函数,因此请将其包含在 LevelStreamerActor.cpp 顶部。

#include "Kismet/GameplayStatics.h"

现在你已准备好创建OverlapBegins功能。在 LevelStreamerActor.cpp 中,开始定义该函数。你可以使用GameplayStatics函数 GetPlayerCharacter 获取索引0处的角色。

void ALevelStreamerActor::OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult) { ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); }

获取MyCharacter后,针对与BoxComponent重叠的OtherActor检查它。此外,验证LevelToLoad是否不为空,然后调用LoadStreamLevel。

if (OtherActor == MyCharacter && LevelToLoad != "") { FLatentActionInfo LatentInfo; UGameplayStatics::LoadStreamLevel(this, LevelToLoad, true, true, LatentInfo); }

在LevelStreamerActor构造函数中,将OverlapBegins绑定到BoxComponent的OnComponentBeginOverlap。

OverlapVolume->OnComponentBeginOverlap.AddUniqueDynamic(this, &ALevelStreamerActor::OverlapBegins);

你的最终 LevelStreamerActor.h 应当如下所示:

#pragma once #include "GameFramework/Actor.h" #include "LevelStreamerActor.generated.h" UCLASS() class LEVELS_API ALevelStreamerActor : public AActor { GENERATED_BODY() public: // 为此Actor的属性设置默认值 ALevelStreamerActor(); // 每一帧都调用 virtual void Tick( float DeltaSeconds ) override; protected: // 当游戏开始或生成时调用 virtual void BeginPlay() override; UFUNCTION() void OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult); UPROPERTY(EditAnywhere) FName LevelToLoad; private: // 重叠体积以触发关卡流送 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) UBoxComponent* OverlapVolume; };

你的最终 LevelStreamerActor.cpp 应当如下所示:

#include "Levels.h" #include "Kismet/GameplayStatics.h" #include "LevelStreamerActor.h" // 设置默认值 ALevelStreamerActor::ALevelStreamerActor() { // 将此Actor设置为每帧调用更新函数()。 如果不需要此特性,可以关闭以提升性能。 PrimaryActorTick.bCanEverTick = true; OverlapVolume = CreateDefaultSubobject(TEXT("OverlapVolume")); RootComponent = OverlapVolume; OverlapVolume->OnComponentBeginOverlap.AddUniqueDynamic(this, &ALevelStreamerActor::OverlapBegins); } // 当游戏开始或生成时调用 void ALevelStreamerActor::BeginPlay() { Super::BeginPlay(); } // 每一帧都调用 void ALevelStreamerActor::Tick( float DeltaTime ) { Super::Tick( DeltaTime ); } void ALevelStreamerActor::OverlapBegins(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult) { ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); if (OtherActor == MyCharacter && LevelToLoad != "") { FLatentActionInfo LatentInfo; UGameplayStatics::LoadStreamLevel(this, LevelToLoad, true, true, LatentInfo); } }

编译你的代码,然后切换回编辑器。

将 LevelStreamer Actor放入关卡中,然后调整位置并缩放,直至它包含你希望 角色 位于其中才能开始流送的持久世界的一部分, 以及流送中的关卡将位于的整个可行走体积。

输入 *SunTemple_Streaming** 作为 **要流送的关卡** 。

使用在编辑器中运行(Play in Editor)来测试流送中的关卡。

使用C++卸载关卡

要在 角色 离开BoxComponent时卸载关卡,你需要创建 OverlapEnds 函数来调用 UGameplayStatics::UnloadStreamLevel 并将函数绑定到 OnComponentEndOverlap 。将以下代码片段添加到 你的LevelStreamerActor:

在LevelStreamerActor.h中:

UFUNCTION() void OverlapEnds(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

在LevelStreamerActor.cpp中:

void ALevelStreamerActor::OverlapEnds(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) { ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); if (OtherActor == MyCharacter && LevelToLoad != "") { FLatentActionInfo LatentInfo; UGameplayStatics::UnloadStreamLevel(this, LevelToLoad, LatentInfo); } }

在构造函数中:

OverlapVolume->OnComponentEndOverlap.AddUniqueDynamic(this, &ALevelStreamerActor::OverlapEnds);


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3