void UEnvQueryGenerator_OnCircle::GenerateItems(FEnvQueryInstance& QueryInstance) const { float AngleDegree = 360.f; float RadiusValue = 0.f; float ItemSpace = 1.0f; if (QueryInstance.GetParamValue(Angle, AngleDegree, TEXT("Angle")) == false || QueryInstance.GetParamValue(Radius, RadiusValue, TEXT("Radius")) == false || QueryInstance.GetParamValue(ItemSpacing, ItemSpace, TEXT("ItemSpacing")) == false || AngleDegree <= 0.f || AngleDegree > 360.f || RadiusValue <= 0.f) { return; } AngleRadians = FMath::DegreesToRadians(Angle.Value); // first generate points on a circle const float CircumferenceLength = 2.f * PI * RadiusValue; const float ArcAnglePercentage = Angle.Value / 360.f; const float ArcLength = CircumferenceLength * ArcAnglePercentage; const int32 StepsCount = FMath::CeilToInt(ArcLength / ItemSpace) + 1; const float AngleStep = AngleDegree / (StepsCount - 1); FVector StartDirection = CalcDirection(QueryInstance); TArray<FVector> CenterLocationCandidates; QueryInstance.PrepareContext(CircleCenter, CenterLocationCandidates); StartDirection = StartDirection.RotateAngleAxis(-AngleDegree/2, FVector::UpVector) * RadiusValue; int NumCenterLocations = CenterLocationCandidates.Num(); if (NumCenterLocations > 0) { for (int i = 0; i < NumCenterLocations; ++i) { GenerateItemsForCircle(CenterLocationCandidates[i], StartDirection, StepsCount, AngleStep, QueryInstance); } } else { FVector CenterLocation(0); AActor* Querier = Cast<AActor>(QueryInstance.Owner.Get()); if (Querier) { CenterLocation = Querier->GetActorLocation(); } GenerateItemsForCircle(CenterLocation, StartDirection, StepsCount, AngleStep, QueryInstance); } }
void UEnvQueryGenerator_OnCircle::GenerateItems(FEnvQueryInstance& QueryInstance) const { CircleRadius.BindData(QueryInstance.Owner.Get(), QueryInstance.QueryID); SpaceBetween.BindData(QueryInstance.Owner.Get(), QueryInstance.QueryID); ArcAngle.BindData(QueryInstance.Owner.Get(), QueryInstance.QueryID); float AngleDegree = ArcAngle.GetValue(); float RadiusValue = CircleRadius.GetValue(); float ItemSpace = SpaceBetween.GetValue(); if ((AngleDegree <= 0.f) || (AngleDegree > 360.f) || (RadiusValue <= 0.f) || (ItemSpace <= 0.f)) { return; } AngleRadians = FMath::DegreesToRadians(AngleDegree); // first generate points on a circle const float CircumferenceLength = 2.f * PI * RadiusValue; const float ArcAnglePercentage = AngleDegree / 360.f; const float ArcLength = CircumferenceLength * ArcAnglePercentage; const int32 StepsCount = FMath::CeilToInt(ArcLength / ItemSpace) + 1; const float AngleStep = AngleDegree / (StepsCount - 1); FVector StartDirection = CalcDirection(QueryInstance); StartDirection = StartDirection.RotateAngleAxis(-AngleDegree/2, FVector::UpVector) * RadiusValue; // gather context with raw data, so it can be used by derived generators FEnvQueryContextData ContextData; const bool bSuccess = QueryInstance.PrepareContext(CircleCenter, ContextData); if (bSuccess && ContextData.ValueType && ContextData.ValueType->IsChildOf(UEnvQueryItemType_VectorBase::StaticClass())) { UEnvQueryItemType_VectorBase* DefTypeOb = (UEnvQueryItemType_VectorBase*)ContextData.ValueType->GetDefaultObject(); const uint16 DefTypeValueSize = DefTypeOb->GetValueSize(); uint8* RawData = ContextData.RawData.GetData(); for (int32 ValueIndex = 0; ValueIndex < ContextData.NumValues; ValueIndex++) { const FVector ContextItemLocation = DefTypeOb->GetItemLocation(RawData); GenerateItemsForCircle(RawData, DefTypeOb, ContextItemLocation, StartDirection, StepsCount, AngleStep, QueryInstance); RawData += DefTypeValueSize; } } }