bool TryAutoTargeting();
bool SearchEnemies();
void ScoreEnemies();
void SetEnemyTarget();
void ClearScores();
TArray<FHitResult> SearchHits;
TArray<AActor*> SearchedEnemies;
TArray<float> DistanceScores;
TArray<float> AngleScores;
TArray<float> TotalScores;
📄 Cpp
bool APlayerCharacter::TryAutoTargeting()
{
if (SearchEnemies() == true)
{
ScoreEnemies();
SetEnemyTarget();
ClearScores();
bIsTargeting = true;
return true;
}
bIsTargeting = false;
return false;
}
bool APlayerCharacter::SearchEnemies()
{
TArray<AActor*> actorToIgnore;
bool outValue = UKismetSystemLibrary::SphereTraceMulti(this, GetActorLocation(), GetActorLocation(), 300.f, TraceTypeQuery3, false, actorToIgnore,
EDrawDebugTrace::ForDuration, SearchHits, true, FColor::Red, FColor::Green, 1.f);
if (outValue == false)
return false;
for (int i = 0; i < SearchHits.Num(); i++)
{
SearchedEnemies.Add(SearchHits[i].GetActor());
}
return true;
}
void APlayerCharacter::ScoreEnemies()
{
for (int i = 0; i < SearchHits.Num(); i++)
{
float dist = FVector::Distance(SearchedEnemies[i]->GetActorLocation(), GetActorLocation());
DistanceScores.Add(dist);
FVector inputVector = GetLastMovementInputVector();
FVector direction = SearchedEnemies[i]->GetActorLocation() - GetActorLocation();
direction.Normalize();
float deltaRadian = FMath::Acos(FVector::DotProduct(inputVector, direction));
float deltaDegree = FMath::RadiansToDegrees(deltaRadian);
AngleScores.Add(deltaDegree);
TotalScores.Add(DistanceScores[i] + AngleScores[i] * 4);
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Cyan, FString::Printf(TEXT("Name:%s, Dist:%f, Angle:%f, Total:%f"),
*SearchHits[i].GetActor()->GetName(), DistanceScores[i], AngleScores[i], TotalScores[i]));
}
}
void APlayerCharacter::SetEnemyTarget()
{
float minScore = 5000.f;
int index = 0;
int outIndex = 0;
for (index; index < SearchHits.Num(); index++)
{
if (TotalScores[index] < minScore)
{
minScore = TotalScores[index];
outIndex = index;
}
}
EnemyTarget = SearchedEnemies[outIndex];
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Red, FString::Printf(TEXT("%s"), *EnemyTarget->GetName()));
}
void APlayerCharacter::ClearScores()
{
SearchHits.Empty();
SearchedEnemies.Empty();
DistanceScores.Empty();
AngleScores.Empty();
TotalScores.Empty();
}