Split out the GetWorld() function to a cached UWorld* assignment and you will notice that it turns up nullptr.
So you need to find a way to get the world context to become valid. Will do some tests and I’ll get back to you if I find a way to get it running.
Ok got it working.
.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "EnvironmentQuery/Generators/EnvQueryGenerator_BlueprintBase.h"
#include "EnvironmentQuery/EnvQueryTypes.h"
#include "EnvQueryGenerator_CoverPoints.generated.h"
/**
*
*/
UCLASS(Blueprintable)
class REPLACEWITHYOUR_API UEnvQueryGenerator_CoverPoints : public UEnvQueryGenerator_BlueprintBase
{
GENERATED_BODY()
public:
UEnvQueryGenerator_CoverPoints(const FObjectInitializer& ObjectInitializer);
virtual void GenerateItems(FEnvQueryInstance& QueryInstance) const override;
//virtual void ProcessItems(FEnvQueryInstance& QueryInstance, TArray<AActor*>& MatchingActors) const {}
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float RayCastRange = 200;
/** trace params */
UPROPERTY(EditDefaultsOnly, Category = Generator)
FEnvTraceData ProjectionData;
void StoreNavPoints(const TArray<FNavLocation>& Points, FEnvQueryInstance& QueryInstance) const;
protected:
/** context */
UPROPERTY(EditDefaultsOnly, Category = Generator)
TSubclassOf<UEnvQueryContext> QueryContext;
};
.Cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "EnvQueryGenerator_CoverPoints.h"
#include "Kismet/GameplayStatics.h"
#include "BehaviorTree/BlackboardData.h"
#include "EnvironmentQuery/Items/EnvQueryItemType_Point.h"
#include "EnvironmentQuery/Contexts/EnvQueryContext_Querier.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(EnvQueryGenerator_CoverPoints)
#define LOCTEXT_NAMESPACE "EnvQueryGenerator"
UWorld* World;
UEnvQueryGenerator_CoverPoints::UEnvQueryGenerator_CoverPoints(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer){
QueryContext = UEnvQueryContext_Querier::StaticClass();
ItemType = UEnvQueryItemType_Point::StaticClass();
}
void UEnvQueryGenerator_CoverPoints::GenerateItems(FEnvQueryInstance& QueryInstance) const
{
TArray<FVector> LocationSet;
UObject* QueryOwner = QueryInstance.Owner.Get();
if (QueryOwner == nullptr)
{
return;
}
World = GEngine->GetWorldFromContextObject(QueryOwner, EGetWorldErrorMode::LogAndReturnNull);
if (World != nullptr)
{
for (int i = 0; i < 36; i++)
{
FRotator Rotator = FRotator::ZeroRotator;
Rotator.Yaw = i * 10;
FVector RotationVector = Rotator.RotateVector(FVector(1, 0, 0));
RotationVector = RotationVector * RayCastRange;
APawn* PlayerPawn = UGameplayStatics::GetPlayerPawn(World, 0);
if (PlayerPawn != nullptr)
{
RotationVector = RotationVector + PlayerPawn->GetActorLocation();
FHitResult HitResult;
if (World->LineTraceSingleByChannel(HitResult, RotationVector, PlayerPawn->GetActorLocation(), ECollisionChannel::ECC_Visibility))
{
LocationSet.Add(HitResult.ImpactPoint);
}
}
}
QueryInstance.PrepareContext(QueryContext, LocationSet);
for (const FVector& Location : LocationSet)
{
FNavLocation NavLoc(Location);
QueryInstance.AddItemData<UEnvQueryItemType_Point>(NavLoc);
// DEBUG TO VISUALIZE DELETE LATER
DrawDebugSphere(World, NavLoc, 50, 32, FColor::Red);
}
}
return;
}
void UEnvQueryGenerator_CoverPoints::StoreNavPoints(const TArray<FNavLocation>& Points, FEnvQueryInstance& QueryInstance) const
{
const int32 InitialElementsCount = QueryInstance.Items.Num();
QueryInstance.ReserveItemData(InitialElementsCount + Points.Num());
for (int32 Idx = 0; Idx < Points.Num(); Idx++)
{
// store using default function to handle creating new data entry
QueryInstance.AddItemData<UEnvQueryItemType_Point>(Points[Idx]);
}
FEnvQueryOptionInstance& OptionInstance = QueryInstance.Options[QueryInstance.OptionIndex];
OptionInstance.bHasNavLocations = (ProjectionData.TraceMode == EEnvQueryTrace::Navigation);
}
#undef LOCTEXT_NAMESPACE
Setting for generator
1 Like
Thank you so much for your help.