Custom UE4 EQS Generators
// Fill out your copyright notice in the Description page of Project Settings. | |
#include "EnvQueryGenerator_GridOffset.h" | |
#include "AI/Navigation/NavigationTypes.h" | |
#include "EnvironmentQuery/Contexts/EnvQueryContext_Querier.h" | |
#define LOCTEXT_NAMESPACE "EnvQueryGenerator" | |
UEnvQueryGenerator_GridOffset::UEnvQueryGenerator_GridOffset() | |
{ | |
GenerateAround = UEnvQueryContext_Querier::StaticClass(); | |
GridHalfSize.DefaultValue = 1000.0f; | |
SpaceBetween.DefaultValue = 200.0f; | |
OffsetSpace.DefaultValue = 500.0f; | |
} | |
void UEnvQueryGenerator_GridOffset::GenerateItems(FEnvQueryInstance& QueryInstance) const | |
{ | |
// Data Binding | |
UObject* BindOwner = QueryInstance.Owner.Get(); | |
GridHalfSize.BindData(BindOwner, QueryInstance.QueryID); | |
SpaceBetween.BindData(BindOwner, QueryInstance.QueryID); | |
OffsetSpace.BindData(BindOwner, QueryInstance.QueryID); | |
float RadiusValue = GridHalfSize.GetValue(); | |
float DensityValue = SpaceBetween.GetValue(); | |
float OffsetValue = OffsetSpace.GetValue(); | |
// Get number of items per row and calculate the indexes ranges for the hole | |
const int32 ItemsCount = FPlatformMath::TruncToInt((RadiusValue * 2.0 / DensityValue) + 1); | |
const int32 ItemsCountHalf = ItemsCount / 2; | |
const int32 LeftRangeIndex = ItemsCountHalf - FPlatformMath::TruncToInt(OffsetValue / DensityValue) - 1; | |
const int32 RightRangeIndex = ItemsCountHalf + FPlatformMath::TruncToInt(OffsetValue / DensityValue) + 1; | |
const int32 OffsetItemsCount = FPlatformMath::TruncToInt((ItemsCount * 2.0 / DensityValue) + 1); | |
// Get locations for each context (we might have more that one context) | |
TArray<FVector> ContextLocations; | |
QueryInstance.PrepareContext(GenerateAround, ContextLocations); | |
// Reserve the needed memory space of items for each context. | |
// the total items count is calculated subtracting the items located into the hole from the total list of items. | |
TArray<FNavLocation> GridPoints; | |
GridPoints.Reserve(((ItemsCount * ItemsCount) - (OffsetItemsCount * OffsetItemsCount)) * ContextLocations.Num()); | |
// Calculate position of each item | |
for (int32 ContextIndex = 0; ContextIndex < ContextLocations.Num(); ContextIndex++) { | |
for (int32 IndexX = 0; IndexX < ItemsCount; ++IndexX) | |
{ | |
for (int32 IndexY = 0; IndexY < ItemsCount; ++IndexY) | |
{ | |
// it the item is inside the hole ranges, just skip it. | |
if ((IndexY > LeftRangeIndex && IndexY < RightRangeIndex) && (IndexX > LeftRangeIndex && IndexX < RightRangeIndex)) { | |
continue; | |
} | |
// starting from the context location, define the location of the current item | |
// and add it to the gridPoints array. | |
else { | |
const FNavLocation TestPoint = FNavLocation(ContextLocations[ContextIndex] - FVector(DensityValue * (IndexX - ItemsCountHalf), DensityValue * (IndexY - ItemsCountHalf), 0)); | |
GridPoints.Add(TestPoint); | |
} | |
} | |
} | |
} | |
// Project all the points, remove those outside the current navmesh and store the result. | |
ProjectAndFilterNavPoints(GridPoints, QueryInstance); | |
StoreNavPoints(GridPoints, QueryInstance); | |
} | |
FText UEnvQueryGenerator_GridOffset::GetDescriptionTitle() const | |
{ | |
return FText::Format(LOCTEXT("GridOffsetDescriptionGenerateAroundContext", "{0}: generate around {1}"), | |
Super::GetDescriptionTitle(), UEnvQueryTypes::DescribeContext(GenerateAround)); | |
}; | |
FText UEnvQueryGenerator_GridOffset::GetDescriptionDetails() const | |
{ | |
FText Desc = FText::Format(LOCTEXT("GridOffseDescription", "radius: {0}, space between: {1}, offset:{2}"), | |
FText::FromString(GridHalfSize.ToString()), FText::FromString(SpaceBetween.ToString()), FText::FromString(OffsetSpace.ToString())); | |
FText ProjDesc = ProjectionData.ToText(FEnvTraceData::Brief); | |
if (!ProjDesc.IsEmpty()) | |
{ | |
FFormatNamedArguments ProjArgs; | |
ProjArgs.Add(TEXT("Description"), Desc); | |
ProjArgs.Add(TEXT("ProjectionDescription"), ProjDesc); | |
Desc = FText::Format(LOCTEXT("GridOffsetDescriptionWithProjection", "{Description}, {ProjectionDescription}"), ProjArgs); | |
} | |
return Desc; | |
} | |
#undef LOCTEXT_NAMESPACE |
// Fill out your copyright notice in the Description page of Project Settings. | |
#pragma once | |
#include "CoreMinimal.h" | |
#include "EnvironmentQuery/Generators/EnvQueryGenerator_ProjectedPoints.h" | |
#include "DataProviders/AIDataProvider.h" | |
#include "SubclassOf.h" | |
#include "EnvQueryGenerator_GridOffset.generated.h" | |
UCLASS() | |
class EQSTUTORIAL_API UEnvQueryGenerator_GridOffset : public UEnvQueryGenerator_ProjectedPoints | |
{ | |
GENERATED_BODY() | |
UEnvQueryGenerator_GridOffset(); | |
UPROPERTY(EditDefaultsOnly, Category = "Grid Parameters") | |
FAIDataProviderFloatValue OffsetSpace; | |
UPROPERTY(EditDefaultsOnly, Category = "Grid Parameters") | |
FAIDataProviderFloatValue GridHalfSize; | |
UPROPERTY(EditDefaultsOnly, Category = "Grid Parameters") | |
FAIDataProviderFloatValue SpaceBetween; | |
UPROPERTY(EditDefaultsOnly, Category = Generator) | |
TSubclassOf<UEnvQueryContext> GenerateAround; | |
virtual void GenerateItems(FEnvQueryInstance& QueryInstance) const override; | |
virtual FText GetDescriptionTitle() const override; | |
virtual FText GetDescriptionDetails() const override; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment