Closest Enemy

Can someone tell me what is going wrong here? It’s a “closest enemy” code.

I want it to only use the enemies with “attackable” tag. Upon doing a test. It’s giving me
all sorts of weird results. It finds the enemy but doesn’t necessarily give me the closest. Even flat out ignoring enemies right up close.

float Distanceval = 10000.f;

FVector myLocation = GetActorLocation();

TArray<AActor*> EnemiesInSphereRadius;
TSubclassOf < APlayerGeo > ClassFilter;
AActor* ClosestActor = nullptr;

// Clear the array
EnemiesInSphereRadius.Empty();

if (EnemiesInSphereRadius.Num() > 0)
{
EnemiesInSphereRadius.RemoveAt(0);
}

// Generate/populate the “EnemiesInSphereRadius” array with the resulting actors that are overlapped

HominCone->GetOverlappingActors(EnemiesInSphereRadius, ClassFilter);

if (EnemiesInSphereRadius.Num() > 0)
{
// Set the initial distance float
float InitialDistance1 = FMath::RoundToPositiveInfinity(900000000.0f);

  for (int32 ActorIndex = 0; ActorIndex < EnemiesInSphereRadius.Num(); ActorIndex++)
  {

  	float ClosestDistance1 = FVector(myLocation - EnemiesInSphereRadius[ActorIndex]->GetActorLocation()).SquaredLength();//SizeSquared(); //.Size();

  	if (!ActorIndex || !EnemiesInSphereRadius[ActorIndex]->ActorHasTag(TEXT("Attackable"))) { continue; }

  	// Get the closest actor by distance to the main character in the array.

  	if (ClosestDistance1 < InitialDistance1)
  	{
  		InitialDistance1 = ClosestDistance1;

  		ClosestActor = EnemiesInSphereRadius[ActorIndex];


  	}
  }

}

Can be a lot of things, have you tried setting breakpoints and reading the values during runtime? Do all the enemies have the proper tags, pass the class filter and have had an overlap with the sphere? Especially the sphere overlap might be a fragile point. If that turns out to be the issue, I get that you likely implemented a sphere near the player for optimization reasons so that you don’t have to iterate through all actors in a level. What I’d do in this case is add an actor component to actors which can be friendly / enemy and let that actor component register itself to a GameInstanceSubsystem whenever it starts playing. then you can request all friendlies / enemies from that subsystem directly. Then you have a much smaller list of actors to iterate through and can drop the overlap system in place if it’s not used for anything else.

float ClosestDistance = SphereRadius;
AActor* ClosestActor = nullptr;

for (AActor* OtherActor : EnemiesInSphereRadius) {
  if (!IsValid(OtherActor) || !OtherActor->ActorHasTag(TEXT("Attackable"))) {
    continue;
  }

  const float Distance = MyActor->GetDistanceTo(OtherActor);
  if (Distance < ClosestDistance) {
    ClosestDistance = Distance;
    ClosestActor = OtherActor;
  }
}

if (ClosestActor == nullptr) {
  return;
}

// DoStuff with ClosestActor