EQS Trace By Profile Name, Ignore channels in trace

So I was playing around with EQS trace and wanted to trace to a location but ignore any pawns blocking the trace, I thought I could use the IgnoreOnlyPawn profile name to do the trace in EQS but found out that it doesn’t work, I took a look at the C++ implementation and correct me if I’m wrong but I think it’s not handled at all, only trace by channel is.

I thought Ok might as well try and create a slightly modified test in C++, below is my code if anyone interested, I handled the profile trace and also added an array of channels you can ignore for trace by channel.

Any suggestion/advice are welcome.

Here’s a demonstration, I’m using a context to return a location of the character rather than an actor pointer, so the trace would not ignore the character, but we can specify a channel to ignore or use a profile name.

// Fill out your copyright notice in the Description page of Project Settings.


#include "EnvQueryTest_LocationVisibility.h"
#include "EnvironmentQuery/Items/EnvQueryItemType_VectorBase.h"
#include "EnvironmentQuery/Contexts/EnvQueryContext_Querier.h"
#include "Kismet/KismetSystemLibrary.h"

UEnvQueryTest_LocationVisibility::UEnvQueryTest_LocationVisibility()
{
	Cost = EEnvTestCost::High;
	ValidItemType = UEnvQueryItemType_VectorBase::StaticClass();
	SetWorkOnFloatValues(false);

	Context = UEnvQueryContext_Querier::StaticClass();
	TraceData.SetGeometryOnly();
}

void UEnvQueryTest_LocationVisibility::RunTest(FEnvQueryInstance& QueryInstance) const
{

	float ItemZ = ItemHeightOffset.GetValue();
	float ContextZ = ContextHeightOffset.GetValue();
	bool bWantsHit = BoolValue.GetValue();

	TArray<FVector> ContextLocations;
	if (!QueryInstance.PrepareContext(Context, ContextLocations))
	{
		return;
	}

	FCollisionQueryParams TraceParams(SCENE_QUERY_STAT(EnvQueryTrace), TraceData.bTraceComplex);
	TArray<AActor*> IgnoredActors;
	if (QueryInstance.PrepareContext(Context, IgnoredActors))
	{
		TraceParams.AddIgnoredActors(IgnoredActors);
	}

	ECollisionChannel TraceCollisionChannel;
	FCollisionResponseParams Response = FCollisionResponseParams::DefaultResponseParam;
	FVector TraceExtent(TraceData.ExtentX, TraceData.ExtentY, TraceData.ExtentZ);

	//Ignore channels, only do this if we're not using a trace by profile.
	if(TraceData.TraceMode == EEnvQueryTrace::GeometryByChannel)
	{
		TraceCollisionChannel = UEngineTypes::ConvertToCollisionChannel(TraceData.TraceChannel);
		if(IgnoreChannels.Num() > 0)
		{
			FCollisionResponseContainer Cnt = FCollisionResponseContainer::GetDefaultResponseContainer();
			for (const ECollisionChannel ChannelToIgnore : IgnoreChannels)
			{
				Cnt.SetResponse(ChannelToIgnore, ECR_Ignore);
			}
			Response = FCollisionResponseParams(Cnt);
		}
	
	}else
	{
		//Load the profile once.
		UCollisionProfile::GetChannelAndResponseParams(TraceData.TraceProfileName, TraceCollisionChannel, Response);
	}
	

	for (int32 ContextIndex = 0; ContextIndex < ContextLocations.Num(); ContextIndex++)
	{
		ContextLocations[ContextIndex].Z += ContextZ;
	}

	for(FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It)
	{
		const FVector ItemLocation = GetItemLocation(QueryInstance, It.GetIndex()) + FVector(0, 0, ItemZ);
		AActor* ItemActor = GetItemActor(QueryInstance, It.GetIndex());

		for (int32 ContextIndex = 0; ContextIndex < ContextLocations.Num(); ContextIndex++)
		{
			const bool Result = RunShapeTraceTo(ItemLocation, ContextLocations[ContextIndex], ItemActor, QueryInstance.World, TraceCollisionChannel, TraceParams, Response, TraceExtent, TraceData.TraceShape);
			It.SetScore(TestPurpose, FilterType, Result, bWantsHit);
		}
	}

}

FText UEnvQueryTest_LocationVisibility::GetDescriptionTitle() const
{
	return FText::FromString(TEXT("Advanced Trace"));
}

FText UEnvQueryTest_LocationVisibility::GetDescriptionDetails() const
{
	return FText::FromString(TEXT("Trace by Channel/Profile"));
}

void UEnvQueryTest_LocationVisibility::PostLoad()
{
	Super::PostLoad();
	TraceData.OnPostLoad();
}

bool UEnvQueryTest_LocationVisibility::RunShapeTraceTo(const FVector& ItemPos, const FVector& ContextPos, AActor* ItemActor, UWorld* World, enum ECollisionChannel Channel, const FCollisionQueryParams& Params, const FCollisionResponseParams& Response, const FVector& Extent, const EEnvTraceShape::Type& Shape) const
{
	FCollisionQueryParams TraceParams(Params);
	TraceParams.AddIgnoredActor(ItemActor);

	switch (Shape)
	{
		case EEnvTraceShape::Line:
			return World->LineTraceTestByChannel(ItemPos, ContextPos, Channel, TraceParams, Response);
		case EEnvTraceShape::Box:
			return World->SweepTestByChannel(ItemPos, ContextPos, FQuat((ItemPos - ContextPos).Rotation()), Channel, FCollisionShape::MakeBox(Extent), TraceParams, Response);
		case EEnvTraceShape::Sphere:
			return World->SweepTestByChannel(ItemPos, ContextPos, FQuat::Identity, Channel, FCollisionShape::MakeSphere(Extent.X), TraceParams, Response);
		case EEnvTraceShape::Capsule:
			return World->SweepTestByChannel(ItemPos, ContextPos, FQuat::Identity, Channel, FCollisionShape::MakeCapsule(Extent.X, Extent.Z), TraceParams, Response);
		default:
			return false;
	}

}