Skip to content

Instantly share code, notes, and snippets.

@ariok
Created June 1, 2019 10:17
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ariok/7ab8576c10ceb14ee6800e9ee694cf89 to your computer and use it in GitHub Desktop.
Save ariok/7ab8576c10ceb14ee6800e9ee694cf89 to your computer and use it in GitHub Desktop.
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