I want to figure out how to load a new level and ‘move’ my character into it when the character overlaps or enters a certain area. Im trying to follow this tutorial:
but there are a few things that i don’t understand, apparently.
I believe I’ve set up the Level window correctly:
and i’ll include my header and source files inline here.
What i expect/hope is that my character would automatically ‘spawn’ into the target level once it enters the ‘OverlapVolume’
What i see instead is that the character is ‘respawned’ at the PlayerStart of the source level and the original instance of the character is still visible stuck as they enter the OverlapVolume - very strange (kind of like this movie i just watched called ‘Triangle’ from 2009 - not a good movie, don’t watch it!).
I’m also unsure what the emphasized text below means in the tutorial:
"Place your LevelStreamer Actor into your level, and adjust the placement and scale until it encompasses the part of the persistent world you want your Character to be in to begin streaming, as well as the entire walkable volume where the streaming level will be."
thank you for any advice you can offer …
LevelStreamerActor.h
#pragma once
include “Components/BoxComponent.h”
include “GameFramework/Actor.h”
include “LevelStreamerActor.generated.h”
UCLASS()
class OFFICE_API ALevelStreamerActor : public AActor {
GENERATED_BODY()
public:
// Sets default values for this actor’s properties
ALevelStreamerActor();
// Called every frame
virtual void Tick(float DeltaSeconds) override;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UFUNCTION()
void OverlapBegins(UPrimitiveComponent *OverlappedComponent,
AActor *OtherActor, UPrimitiveComponent *OtherComp,
int32 OtherBodyIndex, bool bFromSweep,
const FHitResult &SweepResult);
UFUNCTION()
void OverlapEnds(UPrimitiveComponent *OverlappedComponent, AActor *OtherActor,
UPrimitiveComponent *OtherComp, int32 OtherBodyIndex);
UPROPERTY(EditAnywhere)
FName LevelToLoad;
private:
// Overlap volume to trigger level streaming
UPROPERTY(VisibleAnywhere, BlueprintReadOnly,
meta = (AllowPrivateAccess = “true”))
UBoxComponent *OverlapVolume;
};
LevelStreamerActor.cpp
include “LevelStreamerActor.h”
include “Characters/MyCharacter.h”
include “Kismet/GameplayStatics.h”
include “CoreMinimal.h”
ALevelStreamerActor::ALevelStreamerActor() {
PrimaryActorTick.bCanEverTick = true;
OverlapVolume = CreateDefaultSubobject(TEXT(“OverlapVolume”));
RootComponent = OverlapVolume;
OverlapVolume->OnComponentBeginOverlap.AddUniqueDynamic(
this, &ALevelStreamerActor::OverlapBegins);
OverlapVolume->OnComponentEndOverlap.AddUniqueDynamic(
this, &ALevelStreamerActor::OverlapEnds);
}
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);
// comparison of distinct pointer types error unless casted
AActor *MyCharacterAsActor = Cast(MyCharacter);
if (OtherActor == MyCharacterAsActor && LevelToLoad != “”) {
FLatentActionInfo LatentInfo;
UGameplayStatics::LoadStreamLevel(this, LevelToLoad, true, true,
LatentInfo);
}
}
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, true);
}
}