I created a solution based on @MostHost_LA 's suggestion. I created a World Partition Level Load component you add to your player, which fires a load level event once all the given actors are found/hit.
You define N number of lines to do line traces. And define the actor names you need to hit before the level is loaded. If you run it with just the line(s) defined, then you can see all the hit actors’ names in the UE log, which you can use to set the properties. Once you have all your lines and names defined, when you run it it will fire off the loaded event (in C++ and blueprints) once all those actors are loaded.
[ WorldPartitionLoadLevel.h ]
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "WorldPartitionLoadLevelComponent.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FLoadLevelDelegate);
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class SLASH_API UWorldPartitionLoadLevelComponent : public UActorComponent
{
GENERATED_BODY()
public:
UWorldPartitionLoadLevelComponent();
UPROPERTY(BlueprintAssignable, Category = "Level Loaded")
FLoadLevelDelegate OnLevelLoadedDelegate;
UFUNCTION()
void LevelLoaded();
protected:
virtual void BeginPlay() override;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Line Trace")
TArray<FVector> Lines;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Line Trace")
bool bLineTraceOn = true;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Line Trace")
TArray<FString> CheckNames;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Debug")
bool bShowLineDebug = true;
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Debug")
bool bShowDebugMessage = true;
private:
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void RunLineTrace();
bool AllWereHit();
void LineTrace(TArray<FHitResult>& LineHits, FVector EndLine);
bool bStopTrace = false;
UPROPERTY()
TArray<AActor*> HitActors;
UPROPERTY()
TArray<FString> HitNames;
};
[ WorldPartitionLoadLevel.cpp ]
#include "Components/WorldPartitionLoadLevelComponent.h"
#include "Kismet/KismetSystemLibrary.h"
UWorldPartitionLoadLevelComponent::UWorldPartitionLoadLevelComponent()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UWorldPartitionLoadLevelComponent::LevelLoaded()
{
if (bShowDebugMessage) { UE_LOG(LogTemp, Warning, TEXT("World Partition Level Loaded :)")); }
}
void UWorldPartitionLoadLevelComponent::BeginPlay()
{
Super::BeginPlay();
OnLevelLoadedDelegate.AddDynamic(this, &UWorldPartitionLoadLevelComponent::LevelLoaded);
}
void UWorldPartitionLoadLevelComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
RunLineTrace();
}
void UWorldPartitionLoadLevelComponent::RunLineTrace()
{
if (!bStopTrace)
{
TArray<FHitResult> LineHits;
for(FVector Line: Lines)
{
LineTrace(LineHits, Line);
}
if (AllWereHit())
{
bStopTrace = true;
OnLevelLoadedDelegate.Broadcast();
}
}
}
bool UWorldPartitionLoadLevelComponent::AllWereHit()
{
bool allHit = true;
for(FString Name: CheckNames)
{
if (HitNames.Contains(Name))
{
if (bShowDebugMessage) { UE_LOG(LogTemp, Warning, TEXT("Matched Name: %s"), *Name); }
}
else
{
allHit = false;
break;
}
}
return allHit;
}
void UWorldPartitionLoadLevelComponent::LineTrace(TArray<FHitResult>& LineHits, FVector EndLine)
{
AActor* Owner = GetOwner();
TArray<AActor*> ActorsToIgnore;
ActorsToIgnore.Add(Owner);
FVector Start = Owner->GetActorLocation();
FVector End = Start + EndLine;
for(AActor* Actor: HitActors)
{
ActorsToIgnore.AddUnique(Actor);
}
UKismetSystemLibrary::LineTraceMulti(
this,
Start,
End,
TraceTypeQuery1,
false,
ActorsToIgnore,
bShowLineDebug ? EDrawDebugTrace::ForDuration : EDrawDebugTrace::None,
LineHits,
true
);
if (LineHits.Num() > 0)
{
for(FHitResult LineHit : LineHits)
{
AActor* LineHitActor = LineHit.GetActor();
if (!HitActors.Contains(LineHitActor))
{
HitActors.AddUnique(LineHitActor);
HitNames.AddUnique(*LineHit.GetActor()->GetName());
if (bShowDebugMessage) { UE_LOG(LogTemp, Warning, TEXT("Hit Actor: %s"), *LineHit.GetActor()->GetName()); }
}
}
}
}
Player Character Blueprint