How to setup detection in a sphere?

So i’m trying to detect enemies within a certain radius of my AI. To do this i’m using a BT Service that calls OverlapMulti() to get all of the objects within a certain radius. It then checks if each object inherits a class called IDamageable and then checks if they are on the same team or not. If all goes well it determines that they are on opposite teams and can be damaged and attacks it. For some reason though most of the time the AI doesn’t get a target. It will be right next to an enemy and just sit there. After a while sometimes one of them will finally detect an enemy and attack but sometimes it doesn’t happen at all. I’m using the ECC_Pawn trace channel and made sure to set that on all enemies that are being checked but it’s almost like the OverlapMulti() isn’t picking up those objects. I’ve tried almost everything I can think of at this point and am still not having any luck. Let me know if there’s any other information that would be helpful, thanks!

Here is my code to get a target:

void UBTSCheckForTargets::TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds)
{
	Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);

	if (ownerUnit)
	{
		TArray<AActor*> actorsToIgnore;
		actorsToIgnore.Add(ownerUnit);
		FVector start = ownerUnit->GetActorLocation();
		float radius = 720.0f;
		TArray<FOverlapResult> outHits;
		ECollisionChannel traceChannel = ECC_Pawn;

		bool hitOrNot = UGlobalDefinitions::OverlapSphere(actorsToIgnore, outHits, start, radius, traceChannel);

		// Loop through all of the hits
		for (int32 i = 0; i < outHits.Num(); ++i)
		{
			
			// Check to make sure the hit actor can be damaged
			IDamageable* damageableTarget = Cast<IDamageable>(outHits[i].GetActor());
			if (damageableTarget)
			{
				
				// Check to make sure its not friendly
				if (damageableTarget->GetTeam() != ownerUnit->team)
				{
					// Get the key for our targetObject
					targetKey.CacheSelectedKey(BBAsset);
					FBlackboard::FKey targetObject = targetKey.GetSelectedKeyID();

					blackboard->SetValue<UBlackboardKeyType_Object>(targetObject, outHits[i].GetActor());
					return;
				}
				// Else keep looping until we find a valid hit
			}
		}
	}
}

And here is the OverlapSphere function:

// C++ Sphere Overlap Test
bool UGlobalDefinitions::OverlapSphere(TArray<AActor*>& ActorsToIgnore, TArray<FOverlapResult>& OutHits, const FVector& Location, const float Radius, ECollisionChannel TraceChannel)
{

	FCollisionQueryParams TraceParams(FName(TEXT("OverlapMulti Trace")), false);
	TraceParams.bTraceComplex = false;
	TraceParams.bReturnPhysicalMaterial = false;
	TraceParams.AddIgnoredActors(ActorsToIgnore);


	// Get World Source
	TObjectIterator<APlayerController> ThePC;
	if (!ThePC)
	{
		return false;
	}

	// Draw debug lines
	//const FName TraceTag("DebugLines");
	//ThePC->GetWorld()->DebugDrawTraceTag = TraceTag;
	//TraceParams.TraceTag = TraceTag;

	return ThePC->GetWorld()->OverlapMulti(OutHits, Location, FQuat(), TraceChannel, FCollisionShape::MakeSphere(Radius), TraceParams, FCollisionResponseParams(ECollisionResponse::ECR_Overlap));
}

Truthfully, I think you’re better off using something like this…

Let us know if it works for you. :slight_smile:

Thanks! Yeah that seems like a much better approach. I may actually try and use the AIPerception system as in the long term I can do more with it.